SVG动画点线围绕圆形旋转

3
我正在尝试绘制一个圆的线条动画。由于需要在移动设备上运行,因此选择了SVG。我有一个完美的工作示例,但它非常低效,并且会导致页面上的其他动画出现卡顿。
这是我目前拥有的内容和我想要实现的内容:http://jsfiddle.net/sj76ysqs/
<svg class="bean-halo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
   viewBox="0 0 500 500"
   preserveAspectRatio="xMidYMid"
   style="width:100%; height:100%; position:absolute; top:0; left:0;">

    <path d="M200,200 " id="bean-halo" fill="none" stroke="#FF0000" stroke-linecap="round" stroke-width="2.5" stroke-dasharray="0.1,10" />
</svg>

(function() {
    var i = 0,
        circle = document.getElementById('bean-halo'),
        angle = 0,
        radius = 167,
        interval = 20,
        d, radians, x, y, e;

    window.timer = window.setInterval(function() {
        angle -= 5;
        angle %= 360;
        radians = (angle / 180) * Math.PI;
        x = 250 + Math.cos(radians) * radius;
        y = 250 + Math.sin(radians) * radius;
        e = circle.getAttribute('d');
        d = e + (i === 0 ? ' M ' : ' L ') + x + ' ' + y;
        if (angle === -5 && i !== 0) {
            window.clearInterval(window.timer);
            this.beanHaloisDrawn = 1;
        }
        circle.setAttribute('d', d);
        i++;
    }.bind(this), interval);
})()

我想使用以下技术或类似的技术,但我对SVG了解不够,无法实现此目标:http://css-tricks.com/svg-line-animation-works/。我考虑用静态点线来遮盖一个由动态线条揭示的动画线,但同样,我也不知道如何做到这一点。如果您能提供任何帮助,将不胜感激。更新:该解决方案必须适用于具有背景图像的元素。
2个回答

1

那么只需要操作圆的stroke-dasharray属性如何?

<svg class="bean-halo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
   viewBox="0 0 500 500"
   preserveAspectRatio="xMidYMid"
   style="width:100%; height:100%; position:absolute; top:0; left:0;">

    <circle cx="200" cy="200" r="167" id="bean-halo" fill="none" stroke="#FF0000" stroke-linecap="round" stroke-width="2.5" stroke-dasharray="0.1,20000" />
</svg>

一起使用类似这样的东西...
(function() {
            var angle = 0;
            var circle = document.getElementById('bean-halo');
            var dash="0.1,10 ";
            var interval = 20;


            window.timer = window.setInterval(function() {

                circle.setAttribute("stroke-dasharray", dash + " 0, 20000");
                dash = dash + "0.1,10 ";
                if (angle >= 360) window.clearInterval(window.timer);
                angle += 10.1/360;
            }.bind(this), interval);
        })()

如果您不想使用JavaScript,那么您需要自己创建一个包含所有中间步骤的大型动画来进行插值。下面我已经做了4个示例,但是您可以通过使用JavaScript和循环来创建属性。

<svg class="bean-halo" xmlns="http://www.w3.org/2000/svg" 

xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
   viewBox="0 0 500 500"
   preserveAspectRatio="xMidYMid"
   style="width:100%; height:100%; position:absolute; top:0; left:0;">

    <circle cx="200" cy="200" r="167" stroke-width="1" stroke="red" fill="white">

        <animate attributeName="stroke-dasharray" 

values="1,10,0,20000;1,10,1,10,0,20000;1,10,1,10,1,10,0,20000;1,10,1,10,1,10,1,10,0,20000" 

dur="4s" repeatCount="1" fill="freeze" />
   </circle>
</svg>

这个方法很有效,但我希望不使用setInterval。 - mynameisnotallowed

1

使用两个圆的动画技巧,无需编程:

<svg width="400" height="400" viewBox="0 0 400 400" >
    <circle cx="200" cy="200" r="167" stroke-dasharray="1,6" stroke-width="1"  stroke="red" fill="white" />
    <circle cx="200" cy="200" r="167" stroke-dasharray="1200,1200 " stroke-width="3" stroke-dashoffset="0" stroke="white" fill="none">
       <animate attributeType="XML" attributeName="stroke-dashoffset" from="0" to="1200" dur="4s" repeatCount="1" fill="freeze" />
    </circle>
</svg>

看起来很棒!有没有办法让这些线看起来像点呢? - mynameisnotallowed
非常聪明,当然前提是圆圈没有被画在其他任何东西的上面。 - Robert Longson
stroke-linecap="round" 用于点,就像您在原始问题中已经提到的那样。 - Robert Longson
啊,该死。这个圆将会被画在一张图片上:/ - mynameisnotallowed
是的,这个动画技巧有一些注意事项,就是用背景图遮盖顶部圆形的边框,使其看起来无缝连接。 - Alvin K.

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