代码之家  ›  专栏  ›  技术社区  ›  GarethOwen

在SVG中定义圆/弧动画

  •  8
  • GarethOwen  · 技术社区  · 15 年前

    有人知道如何在SVG中定义动画弧/圆,使弧从0度开始到360度结束吗?

    7 回复  |  直到 8 年前
        1
  •  6
  •   Vinay    11 年前

    您可以使用路径的线条“手动”绘制它并计算弧的位置:

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
       viewBox="0 0 1200 800"
       preserveAspectRatio="xMidYMid"
       style="width:100%; height:100%; position:absolute; top:0; left:0;"
       onload="drawCircle();"> 
      <script> 
        function drawCircle() {
            var i = 0;
            var circle = document.getElementById("arc");
            var angle = 0;
            var radius = 100;     
            window.timer = window.setInterval(
            function() {
                angle -=5;  
                angle %= 360;
                var radians= (angle/180) * Math.PI;
                var x = 200 + Math.cos(radians) * radius;
                var y = 200 + Math.sin(radians) * radius;
                var e = circle.getAttribute("d");
                if(i==0) {
                    var d = e+ " M "+x + " " + y;
                }
                else {
                    var d = e+ " L "+x + " " + y;
                }
                if (angle === -5 && i !== 0) {
                    window.clearInterval(window.timer);
                }
    
                circle.setAttribute("d", d);
                i++;
            } 
          ,10)
        }
        </script> 
    
        <path d="M200,200 " id="arc" fill="none" stroke="blue" stroke-width="2" />
    </svg>
    

    http://jsfiddle.net/k99jy/138/

        2
  •  6
  •   Erik Dahlström    15 年前

    一种方法是使用圆,并对 stroke-dashoffset (您也需要“stroke dasharray”)。可以看到这样一个动画的例子(不带圆圈,但同样的原理适用)。 here .

    另一个选项是使用路径动画,以及 arc path segments ,对于路径之间的动画/变形,请参见 example .

        3
  •  4
  •   Raphael Rafatpanah    9 年前

    您还可以使用 circle 以及以下技术:

    1. 给予 圆圈 stroke .
    2. 使 dashed 短划线的长度等于圆的周长。
    3. 抵销 长度等于圆的周长。
    4. 为笔划设置动画。

    HTML:

    <svg width="200" height="200">
      <circle class="path" cx="100" cy="100" r="96" stroke="blue" stroke-width="4" fill="none" />
    </svg>
    

    CSS:

    circle {
      stroke-dasharray: /* circumference */;
      stroke-dashoffset: /* circumference */;
      animation: dash 5s linear forwards;
    }
    
    @keyframes dash {
      to {
        stroke-dashoffset: /* length at which to stop the animation */;
      }
    }
    

    jsfiddle

    来源: https://css-tricks.com/svg-line-animation-works/

        4
  •  3
  •   Patrick Dark    8 年前

    或者您可以打开一个预先绘制的圆,以获得所需的效果:

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" width="400" height="400">
      <rect x="0" y="0" width="1000" height="1000"/>
      <circle cx="500" cy="500" r="500" fill="red"/>
      <rect x="0" y="500" width="1000" height="500"/>
      <rect x="0" y=  "0" width="1000" height="500">
        <animateTransform attributeName="transform" type="rotate" begin="0s" dur="5s" fill="freeze" from="0,500,500" to="180,500,500"/>
      </rect>
    </svg>
    
        5
  •  2
  •   long-lazuli    10 年前

    我也有点不明白,不能简单地用百分之一或一个角来画一个圆的弧。

    现在,当我需要一条不是长路径一部分的弧时,我使用圆和strokedasharray技巧来显示这个圆的一部分。

    svg {
      outline: solid;
      height: 100px;
      width: 100px;
    }
    .arc {
      fill: transparent;
      stroke-width: 5;
      stroke: red;
      stroke-dasharray: 94.24778 219.91149;
    }
    <svg viewport="0 0 100 100">
      <circle cx="50" cy="50" r="50" class="arc"></circle>
    </svg>

    你可以看到一个改进的版本 here 使用sass进行计算。

        6
  •  2
  •   tdjprog    10 年前

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <link rel="stylesheet" href="">
    </head>
    <body>
        
    </body>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
       viewBox="0 0 1200 800"
       preserveAspectRatio="xMidYMid"
       style="width:100%; height:100%; position:absolute; top:0; left:0;"
       onload="drawCircle();"> 
      <script> 
        function drawCircle() {
            // center point
            var cX = 300,
                cY = 300;
                radius = 300,
    
                p1 = {x: cX+radius, y: cY},
                p2 = {x: cX-radius, y: cY},
    
                circle = document.getElementById("arc"),
                angle = 0;
    
            window.timer = window.setInterval(
                function() {
                angle -= 5;  
                angle %= 360;
                var radians= (angle/180) * Math.PI;
                var x = cX + Math.cos(radians) * radius;
                var y = cY + Math.sin(radians) * radius;
    
                if (Math.abs(angle) < 180 && angle != 0)
                    d= 'M ' + p1.x + ',' + p1.y + ' A' + radius+ ',' + radius+ (Math.abs(angle)==180?' 0 1 0 ':' 0 0 0 ')+x+' '+y;
                else
                    d= 'M ' + p1.x + ',' + p1.y + ' A' + radius+ ',' + radius+ ' 0 1 0 '+p2.x+' '+p2.y +
                ' M ' + p2.x + ',' + p2.y + ' A' + radius+ ',' + radius+ (Math.abs(angle)==0?' 0 1 0 ':' 0 0 0 ')+x+' '+y;
                
                circle.setAttribute("d", d);
    
                if (Math.abs(angle) == 0)
                    window.clearInterval(window.timer);
            } 
          ,10)
        }
        </script> 
        <path d="" id="arc" fill="none" stroke="blue" stroke-width="2" />
    </svg>
    </html>
        7
  •  -1
  •   GarethOwen    15 年前

    感谢您的回答-以下是有关我为什么要在SVG中动画一个圆的更多信息:

    我们有一个服务器客户端应用程序。我计划生成SVG图像来表示服务器上的图表(饼图/条形图),并将SVG发送给客户机。 我们有Java和.NET客户端。我将编写客户端代码来解析和呈现从服务器接收的SVG图像。 我计划只使用SVG格式的一个子集-不超过我们表示图表所需的内容,但动画是一项要求。

    长期以来,有一个Ajax客户机会很好,它将运行在浏览器上,而没有Java或.NET运行时。这就是我选择SVG格式的原因。

    对于一个短期的解决方案,我现在认为我将添加我自己的元素到SVG,使用开始和扫描角度定义一个弧。然后我可以通过设置扫描角度的动画来轻松定义所需的动画,并使我的实现变得简单。

    从长远来看,如果我们真的打算使用Ajax/HTML客户机,我将不得不重新实现并坚持SVG标准。

    推荐文章