【问题标题】:Animate SVG circle around the circumference of another SVG circle, using RAF使用 RAF 围绕另一个 SVG 圆的圆周制作 SVG 圆的动画
【发布时间】:2018-03-13 21:14:04
【问题描述】:

我目前正在尝试学习如何使用 requestAnimationFrame 制作动画,但在弄清楚如何在 SVG 圆的圆周上从点到点制作动画时遇到了一些问题。我能够在目标周围找到适当的点,但是当我执行我的函数时,它会直接动画到最后一个点,而所需的效果是遍历整个点列表并按顺序对每个点进行动画处理。

window.onload = function(){
    var little = document.getElementById("little");
    var big = document.getElementById("group");
    var count = 33;
    var cx = 100;
    var cy = 100;
    var r = 66;
    var px;
    var py;

    function animator(){
        for(var i=0; i<count; i++){
            px = cx + r * Math.cos(2*Math.PI*i/count);
            py = cy + r * Math.sin(2*Math.PI*i/count);
            little.setAttribute("cx", px);
            little.setAttribute("cy", py);
            requestAnimationFrame(animator);
        }
    }

        requestAnimationFrame(animator);

}

小提琴:https://jsfiddle.net/jayboodev737/6yrhu785/3/

我认为问题在于我如何尝试实施 RAF 本身,但我对应该如何构建它有点茫然。谢谢!

【问题讨论】:

  • ~~gee~~ 每次调用requestAnimationFrame(callback) 时,callback 都会堆积在下次屏幕刷新时应调用的函数列表中。在这里,您将在 for 循环的每次迭代中添加一个新回调:如果 count 为 2,则在第二帧,animator 将被调用两次,在第三帧将被调用 4 次,这样会以指数方式消耗 CPU 和内存。请在你的循环之后移动它。
  • 同理,您在这个 for 循环中更改单个元素的属性,这是没有意义的,只将其设置为最后一个值会产生相同的效果。

标签: javascript svg requestanimationframe


【解决方案1】:

您不应该在 animator() 函数中循环遍历所有值。动画师功能应该自己执行一个步骤。然后它会调用requestAnimationFrame() 来安排稍后的下一次迭代。

//window.onload = function() {
    var little = document.getElementById("little");
    var big = document.getElementById("group");
    var count = 33;
    var cx = 100;
    var cy = 100;
    var r = 66;
    var i = 0;

    function animator(){
      if (i === count)
        return;

      var px = cx + r * Math.cos(2*Math.PI*i/count);
      var py = cy + r * Math.sin(2*Math.PI*i/count);
      little.setAttribute("cx", px);
      little.setAttribute("cy", py);
      i += 1;
      requestAnimationFrame(animator);
    } 

    requestAnimationFrame(animator);
//}
svg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

.container {
  position: relative;
  height: 100%;
}
<svg viewbox="0 0 600 600" preserveAspectRatio="xMidYMid">
    <defs>
        <clipPath id="clipper">
            <text x="50" y="50" text-anchor="middle" alignment-baseline="middle" font-size="12">FireStarter</text>
        </clipPath>
        <pattern id="patty" x="0" y="0" width=".25" height=".25">
            <rect x="0" y="0" width="800" height="800" style="fill:#7047C2;"></rect>
            <g id="group">
                <circle id="little" cx="166" cy="100" r="11" style="fill:#57FA00;" fill-opacity="0.7"></circle>
                <circle id="big" cx="100" cy="100" r="66" style="fill:#2A0033;" fill-opacity="0.3"></circle>
            </g>
        </pattern>
    </defs>
    <rect x="0" y="0" width="800" height="800" style="fill:url(#patty); transform:translate(-50%, -25%);"></rect>
</svg>

【讨论】:

  • 完美先生!感谢您的反馈
猜你喜欢
  • 2021-06-24
  • 1970-01-01
  • 2019-09-04
  • 1970-01-01
  • 2017-06-24
  • 2017-01-16
  • 2015-07-04
  • 2014-11-28
  • 1970-01-01
相关资源
最近更新 更多