围绕圆圈复制动画

时间:2016-03-31 05:36:38

标签: css css3 css-animations css-shapes

我有一个动画片,用于围绕圆形图像爆炸的“烟花”,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度复制一次的最好方法?我尝试创建一个从顶部出来的,但我不认为我可以继续使用此margin属性进行相同的头/尾效果。我已经读过围绕圆圈放置的东西(Position icons into circle),但我需要保持相同的径向动画效果,这让我很难过。

1 个答案:

答案 0 :(得分:5)

使用CSS:

使用纯CSS的单个元素做你正在寻找的东西将是非常艰难的(如果不是不可能的话)。我们可以通过使用与no一样多的元素来实现。需要的辐条。将辐条绝对放置在某个位置并按所需角度旋转。原点应该固定在元素的底部,这样它们都会聚合成一个点。

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

&#13;
&#13;
.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;
  }
}
&#13;
<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>
&#13;
&#13;
&#13;

注意:没有。如果使用伪元素,可以大大减少元素,但我会留给你。

在中心不会见的行

如果你需要它们不会聚合到一个点并且看起来它们是分开但放在一个圆圈附近那么动画会变得有点复杂。它需要一个梯度,该梯度对于其一半大小是透明的并且对另一个大小是着色的。通过设置背景的大小和位置,可以实现所需的效果。

背景位置中的calc非常重要,因为它会使渐变相对于元素的底部定位,从而使动画按预期工作。

&#13;
&#13;
.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);
  }
}
&#13;
<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>
&#13;
&#13;
&#13;

使用SVG:

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

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

在中心会面的行:

对于此效果,必须创建线条,使得第一个坐标(x,y)将是虚圆(32,32)的中心。对于第二个坐标,我们应该根据线的角度在虚圆上找到点。公式描述为here

注意:在SVG中,0度对应于3 o&#clock时钟位置。

&#13;
&#13;
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 */
  }
}
&#13;
<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>
&#13;
&#13;
&#13;

在中心不会见的行(但他们的预测会发生)

对于这个效果,我们应该为两个坐标找到两个圆的点。第一个坐标将位于半径小于第一个坐标的内圆上(本演示中为16)。第二个将在更大的圆上(本演示中半径= 32)。

&#13;
&#13;
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 */
  }
}
&#13;
<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>
&#13;
&#13;
&#13;