围绕圆形复制动画

3
我有一个“烟花”的动画,它将在一个圆形图像周围爆炸,有10个均匀间隔的射线像车轮辐条一样伸展出来。每个“辐条”都会扩展到最大长度,使“尾巴”赶上“头部”,最后消失。我已经把第一个从底部弄出来了:
HTML:
<div id="firework"></div>

CSS:
#firework {
  background-color: red;
  border-radius: 30%;
  height: 0px;
  margin: 0px 0px;
  width: 2px;
  -webkit-animation: firework-0 1s 1;
}


@-webkit-keyframes firework-0 {
  0% {
    height: 0px;
    margin-top: 0px;
  }
  50% {
    height: 64px;
    margin-top: 0px;
  }
  100% {
    height: 0px;
    margin-top: 64px;
  }
}

小提琴: http://jsfiddle.net/xcWge/1407/ 如何以36度的间隔复制这个效果?我尝试创建从顶部出来的那个,但我不认为我可以继续使用相同的边距属性来实现相同的头/尾效果。我已经阅读了关于在圆周上放置物品的文章(Position icons into circle),但我需要保持相同的径向动画效果,这让我感到困惑。
1个回答

5

使用CSS:

仅使用纯CSS一个元素实现您所需的效果将非常困难(如果不是不可能的)。我们可以通过使用与所需辐条数量相同的元素来完成。将辐条绝对定位到特定位置并旋转所需角度。原点应该固定在元素底部,以便它们全部汇聚成一个点。

动画本身可以通过使用linear-gradient并动画其位置来实现。

.firework {
  position: absolute;
  top: 100px;
  left: 100px;
  border-radius: 30%;
  height: 64px;
  width: 2px;
  background: linear-gradient(to top, red, red);
  background-repeat: no-repeat;
  background-size: 100% 64px;
  background-position: 0px -64px;
  transform-origin: bottom;
  animation: firework-0 1s 1;
}
.firework:nth-child(2){
  transform: rotate(36deg)
}
.firework:nth-child(3){
  transform: rotate(72deg)
}
.firework:nth-child(4){
  transform: rotate(108deg)
}
.firework:nth-child(5){
  transform: rotate(144deg)
}
.firework:nth-child(6){
  transform: rotate(180deg)
}
.firework:nth-child(7){
  transform: rotate(216deg)
}
.firework:nth-child(8){
  transform: rotate(252deg)
}
.firework:nth-child(9){
  transform: rotate(288deg)
}
.firework:nth-child(10){
  transform: rotate(324deg)
}

@keyframes firework-0 {
  0% {
    background-position: 0px 64px;
  }
  50% {
    background-position: 0px 0px;
  }
  100% {
    background-position: 0px -64px;
  }
}
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>

注意:如果使用伪元素,元素的数量可以大大减少,但我会留给你处理。
不在中心相遇的线条:
如果您需要它们不会汇聚到一个点,并且看起来像是分开放置在一个圆周上,那么动画就变得更加复杂。这将需要一个渐变,其透明度为其大小的一半,颜色为另一半。通过动画背景的大小和位置,可以实现所需的效果。
背景位置中的 calc 是关键,因为它使渐变相对于元素底部定位,从而使动画按预期工作。

.firework {
  position: absolute;
  top: 100px;
  left: 100px;
  border-radius: 30%;
  height: 64px;
  width: 2px;
  background: linear-gradient(to top, transparent 32px, red 32px);
  background-repeat: no-repeat;
  background-size: 100% 64px;
  background-position: 100% calc(100% - 32px);
  transform-origin: bottom;
  animation: firework-0 1s 1;
}
.firework:nth-child(2) {
  transform: rotate(36deg)
}
.firework:nth-child(3) {
  transform: rotate(72deg)
}
.firework:nth-child(4) {
  transform: rotate(108deg)
}
.firework:nth-child(5) {
  transform: rotate(144deg)
}
.firework:nth-child(6) {
  transform: rotate(180deg)
}
.firework:nth-child(7) {
  transform: rotate(216deg)
}
.firework:nth-child(8) {
  transform: rotate(252deg)
}
.firework:nth-child(9) {
  transform: rotate(288deg)
}
.firework:nth-child(10) {
  transform: rotate(324deg)
}
@keyframes firework-0 {
  0% {
    background-size: 100% 32px;
    background-position: 100% calc(100% - 0px);
  }
  50% {
    background-size: 100% 64px;
    background-position: 100% calc(100% - 0px);
  }
  100% {
    background-size: 100% 32px;
    background-position: 100% calc(100% - 32px);
  }
}
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>
<div class="firework"></div>

使用SVG:

对于这样的效果,我的建议是使用SVG,因为SVG是创建它们的正确工具。而且相当简单易于创建和维护。

我们所需要的只是10个line元素,从一个点画一条线到另一个点,给它一个虚线填充,然后通过动画stroke-dashoffset来获得所需的效果。

交汇于中心的线:

对于这种效果,必须创建这样的线,使第一个坐标(x,y)成为想像圆形(32,32)的中心。对于第二个坐标,则应根据该线的角度在想象的圆上找到点。 公式在此处描述。

注意:在SVG中,0度对应于3点钟位置。

svg{
  width: 128px;
  height: 128px;
}
line{
  stroke: red;
  animation: firework 1s 1;
  stroke-dasharray: 32 32; /* radius radius */
  stroke-dashoffset: -32; /* -radius */
}
@keyframes firework{
  from{
    stroke-dashoffset: 32; /* radius */
  }
  to{
    stroke-dashoffset: -32; /* -radius */
  }
}
<svg viewBox='0 0 64 64'>
  <g>
    <line x1='32' y1='32' x2='32' y2='0' />
    <line x1='32' y1='32' x2='50.80' y2='6.11' />
    <line x1='32' y1='32' x2='62.43' y2='22.11' />
    <line x1='32' y1='32' x2='62.43' y2='41.88' />
    <line x1='32' y1='32' x2='50.80' y2='57.88' />
    <line x1='32' y1='32' x2='32' y2='64' />
    <line x1='32' y1='32' x2='13.19' y2='57.88' />
    <line x1='32' y1='32' x2='1.56' y2='41.88' />
    <line x1='32' y1='32' x2='1.56' y2='22.11' />
    <line x1='32' y1='32' x2='13.19' y2='6.11' />
  </g>
</svg>

不在中心相遇的直线:(但它们的投影将会相遇)

为了实现这个效果,我们需要找到两个圆上的点来确定两个坐标。第一个坐标将位于内部圆上,其半径比第一个圆小(在此演示中为16)。第二个坐标将位于更大的圆上(在此演示中,半径为32)。

svg{
  width: 128px;
  height: 128px;
}
line{
  stroke: red;
  animation: firework 1s 1;
  stroke-dasharray: 16 16; /* length of the line length of the line */
  stroke-dashoffset: -16; /* -length */
}
@keyframes firework{
  from{
    stroke-dashoffset: 16; /* length */
  }
  to{
    stroke-dashoffset: -16; /* length */
  }
}
<svg viewBox='0 0 64 64'>
  <g>
    <line x1='32' y1='16' x2='32' y2='0' />
    <line x1='41.40' y1='19.05' x2='50.80' y2='6.11' />
    <line x1='47.21' y1='27.05' x2='62.43' y2='22.11' />
    <line x1='47.21' y1='36.94' x2='62.43' y2='41.88' />
    <line x1='41.40' y1='44.94' x2='50.80' y2='57.88' />
    <line x1='32' y1='48' x2='32' y2='64' />
    <line x1='22.59' y1='44.94' x2='13.19' y2='57.88' />
    <line x1='16.78' y1='36.94' x2='1.56' y2='41.88' />
    <line x1='16.78' y1='27.05' x2='1.56' y2='22.11' />
    <line x1='22.59' y1='19.05' x2='13.19' y2='6.11' />
  </g>
</svg>


1
这太完美了!谢谢。 - Brandon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接