使用 RAF 围绕另一个 SVG 圆的圆周动画 SVG 圆
Animate SVG circle around the circumference of another SVG circle, using RAF
我目前正在尝试学习如何使用 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);
}
Fiddle: https://jsfiddle.net/jayboodev737/6yrhu785/3/
我认为问题出在我如何尝试实施 RAF 本身,但对于如何构建它我有点不知所措。谢谢!
您不应该在 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>
我目前正在尝试学习如何使用 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);
}
Fiddle: https://jsfiddle.net/jayboodev737/6yrhu785/3/
我认为问题出在我如何尝试实施 RAF 本身,但对于如何构建它我有点不知所措。谢谢!
您不应该在 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>