【问题标题】:How can I gradually animate path to be circle using Rapheal.js library如何使用 Rapheal.js 库逐渐为圆形路径设置动画
【发布时间】:2012-07-14 00:01:06
【问题描述】:

我有一个圆形扇形,我想让扇形逐渐动画成一个完整的圆形,如何使用 Rapheal.js 制作。

顺便说一句,我是 SVG 新手,我正在使用 svg-editor 使用 SVG 绘制形状。

这是我的代码

  var arcPath1 = paper.path("m325.30255,127.93972c33.86002,6.238 52.02301,8.85 90.823,49.616l105.53491,-65.494c-44.84491,-59.9466 -101.70261,-109.25547 -201.98761,-108.83956l5.6297,124.71756z");

arcPath1.attr({
    "fill": "#003a60",
    stroke: 'none'
});

arcPath1.rotate(1.0569896697998047 ,420.6666870117177,90.38764953613116);
arcPath1.node.id= "arch1";

这是我的代码示例http://jsfiddle.net/v2KeV/

如何使动画完成路径成为一个完整的圆圈?

注意:我制作的动画只是为了测试路径动画..

【问题讨论】:

    标签: javascript html path svg raphael


    【解决方案1】:

    嗯,首先要做的事情是:为了优雅地为弧线段设置动画,我们需要能够以编程方式生成它们。考虑一下这个笨拙的三角函数:

    // arcPath:
    // cx, cy are the center point
    // inner_radius and outer_radius describe the distance of the arc segment's inner and outer boundaries from the center point.
    // starting_radians describes the offset of the segment start;
    // arc_radians describes the width of the arg segment.
    
    function arcPath( cx, cy, inner_radius, outer_radius, starting_radians, arc_radians )
    {
        var x1 = cx + Math.cos( starting_radians ) * inner_radius;
        var y1 = cy + Math.sin( starting_radians ) * inner_radius;
        var x2 = cx + Math.cos( starting_radians ) * outer_radius;
        var y2 = cy + Math.sin( starting_radians ) * outer_radius;
        var x3 = cx + Math.cos( starting_radians + arc_radians ) * outer_radius;
        var y3 = cy + Math.sin( starting_radians + arc_radians ) * outer_radius;
        var x4 = cx + Math.cos( starting_radians + arc_radians ) * inner_radius;
        var y4 = cy + Math.sin( starting_radians + arc_radians ) * inner_radius;
    
        var pathstr = "M" + x1 + "," + y1 + " "
                        + "L" + x2 + "," + y2 + " "
                        + "A" + outer_radius + "," + outer_radius + " " + arc_radians + " " + ( arc_radians > Math.PI ? "1" : "0" ) + " 1 " + x3 + "," + y3 + " "
                        + "L" + x4 + "," + y4 + " "
                        + "A" + inner_radius + "," + inner_radius + " " + ( 0 - arc_radians ) + " " + ( arc_radians > Math.PI ? "1" : "0" ) + " 0 " + x1 + "," + y1 + " z";
    
         return pathstr;                   
    }        
    

    使用更简单的几何构造,您可以简单地为从部分弧段到整个弧段的路径设置动画,然后让 Raphael 进行提升,如下所示:

    var arcPath1 = paper.path(arcPath( 150, 150, 75, 125, Math.PI / 2, Math.PI * 0.65 ) )
        .attr({ fill: "#003a60", 'fill-opacity': 0.5, stroke: 'black' });
    
    arcPath1.click(function () 
        {
            arcPath1.animate( { path: arcPath( 150, 150, 75, 125, Math.PI / 2, Math.PI * 2 - 0.0001 ) }, 2000, "<>" );
        });
    

    不幸的是,Raphael 在这方面做得非常糟糕,因此你会看到大量相交的弧段将自己重新塑造成一个完整的圆,而不是所需的弧形扫描。所以为了让它做你想做的事,我们必须手动执行动画。

    function arcSweep( arc, x, y, inner, outer, angle_offset, from_sweep, to_sweep, duration )
    {
        var steps = 100;
        var current_step = 0;
        var intervalID = setInterval( function()
                     {
                         current_step++;
                         if ( current_step >= steps )
                             clearInterval( intervalID );
                         arc.attr( { path: arcPath( x, y, inner, outer, angle_offset, from_sweep + ( ( to_sweep - from_sweep ) * ( current_step / steps ) ) ) } );
                     }, duration / steps );
    }
    

    所以基本上我们只是计算一系列中间弧并按顺序建立它们,直到我们达到目标角度。除了目标结束角度之外,动画函数还需要弧的所有原始参数(不能是 Math.PI * 2 - 因为它计算为空弧段!)。可能需要将其抽象为一个类,以便弧段的每个实例都可以跟踪自己的变量。

    这是一个fiddle 演示成品。

    【讨论】:

      猜你喜欢
      • 2019-03-22
      • 1970-01-01
      • 2021-05-09
      • 2023-01-30
      • 1970-01-01
      • 2016-08-27
      • 2014-05-24
      • 1970-01-01
      • 2012-02-15
      相关资源
      最近更新 更多