如何逐步绘制矢量路径?(Raphael.js)

Ant*_*off 31 javascript animation svg bezier vector

如何为矢量路径设置动画,就像它正在逐渐被绘制一样?换句话说,逐个像素地慢慢显示路径.

我正在使用Raphaël.js,但是如果你的答案不是特定于库的 - 也许有一些通用的编程模式来做这种事情(我对矢量动画很新) - 欢迎!


使用直线路径很容易,就像该页面上的示例一样简单::

path("M114 253").animate({path: "M114 253 L 234 253"});
Run Code Online (Sandbox Code Playgroud)

但尝试改变该页面上的代码,比如说,这样::

path("M114 26").animate({path: "M114 26 C 24 23 234 253 234 253"});
Run Code Online (Sandbox Code Playgroud)

你会明白我的意思.从初始状态(点"M114 26")到结束状态(曲线"C 24 23 234 253 234 253",从点"M114 26"开始),路径肯定是动画的,但不是以有问题的方式指定,不是像它正在被吸引.

我不知道怎么animateAlong能这样做.它可以沿着路径为对象设置动画,但是如何在对象沿着它进行动画处理时使这条路径逐渐显示出来?


解决方案?

(通过peteorpeter的回答.)

似乎目前最好的方法是使用原始SVG通过'假'破折号.有关说明,请参阅本演示本文档,第4页.

如何制作渐进式绘图?

我们必须使用stroke-dasharraystroke-dashoffset知道要绘制的曲线长度.此代码在屏幕上不显示圆形,椭圆形,折线,多边形或路径:

<[element] style="stroke-dasharray:[curve_length],[curve_length]; stroke-dashoffset:[curve_length]"/>
Run Code Online (Sandbox Code Playgroud)

如果在animate元素stroke-dashoffset减少到0,我们将逐步绘制曲线.

<circle cx="200" cy="200" r="115"
    style="fill:none; stroke:blue; stroke-dasharray:723,723; stroke-dashoffset:723">
    <animate begin="0" attributeName="stroke-dashoffset"
        from="723" to="0" dur="5s" fill="freeze"/>
</circle>
Run Code Online (Sandbox Code Playgroud)

如果你知道更好的方法,请留下答案.


更新(2012年4月26日):找到一个很好地说明这个想法的例子,参见AnimatedBézierCurves.

dav*_*nke 26

也许有人正在寻找答案,就像我现在两天一样:

// Draw a path and hide it:
var root = paper.path('M0 50L30 50Q100 100 50 50').hide();
var length = root.getTotalLength();

// Setup your animation (in my case jQuery):
element.animate({ 'to': 1 }, {
    duration: 500,
    step: function(pos, fx) {
        var offset = length * fx.pos;
        var subpath = root.getSubpath(0, offset);
        paper.clear();
        paper.path(subpath);
    }
});
Run Code Online (Sandbox Code Playgroud)

这对我来说只是通过使用RaphaelJS方法.

这是评论中要求的jsFiddle示例,http://jsfiddle.net/eA8bj/

  • 我已经调整了你的jsFiddle,所以它被隔离到一个raphael路径元素:[http://jsfiddle.net/eA8bj/63/](http://jsfiddle.net/eA8bj/63/) (2认同)

pet*_*ter 17

找到了!(也许 - 假设你在拉斐尔的友好领域之外走进纯净的SVG土地......)

您可以使用SVG keyTimeskeySplines.

这是一个有效的例子:

http://www.carto.net/svg/samples/animated_bustrack.shtml

......这里有一些可能有用的解释:

http://msdn.microsoft.com/en-us/library/ms533119(v=vs.85).aspx


Kev*_*sen 11

我想提供一个替代的,Raphael + JS-only解决方案,我已经在我自己的工作中充分利用了它.它比davidenke的解决方案有几个优点:

  1. 不会在每个循环中清除纸张,允许动画路径与其他元素很好地共存;
  2. 重复使用拉斐尔自己的渐进动画的单一路径,使动画更流畅;
  3. 资源密集程度大大降低.

这是方法(可以很容易地重新组合成一个扩展):

function drawpath( canvas, pathstr, duration, attr, callback )
{
    var guide_path = canvas.path( pathstr ).attr( { stroke: "none", fill: "none" } );
    var path = canvas.path( guide_path.getSubpath( 0, 1 ) ).attr( attr );
    var total_length = guide_path.getTotalLength( guide_path );
    var last_point = guide_path.getPointAtLength( 0 );
    var start_time = new Date().getTime();
    var interval_length = 50;
    var result = path;        

    var interval_id = setInterval( function()
    {
        var elapsed_time = new Date().getTime() - start_time;
        var this_length = elapsed_time / duration * total_length;
        var subpathstr = guide_path.getSubpath( 0, this_length );            
        attr.path = subpathstr;

        path.animate( attr, interval_length );
        if ( elapsed_time >= duration )
        {
            clearInterval( interval_id );
            if ( callback != undefined ) callback();
                guide_path.remove();
        }                                       
    }, interval_length );  
    return result;
}
Run Code Online (Sandbox Code Playgroud)

以下是我网站上使用的两个示例:一个用于路径转换,另一个用于渐进式刻字.


Bra*_*riy 6

使用" pathLength "属性,我们可以将虚拟长度设置为路径.从那时起,我们可以在"stroke-dasharray"中使用这个虚拟长度.因此,如果我们将"pathLength"设置为100个单位,那么我们可以将"stroke-dasharray"设置为"50,50",这将是50%,50%的路径!

这种方法存在一个问题:唯一支持此属性的浏览器是Opera 11.

是没有javascript或硬编码长度的平滑曲线drawind动画的示例.(仅在Opera 11中正常工作)


abe*_*ier 5

我已经为此创建了一个脚本:Scribble.js,基于这个伟大的dasharray/dashoffset技术.

只是在一堆SVG上实例化它<path>:

var scribble = new Scribble(paths, {duration: 3000});
scribble.erase();
scribble.draw(function () {
    // done
});
Run Code Online (Sandbox Code Playgroud)

-

NB:完整USAGE代码:https://gist.github.com/abernier/e082a201b0865de1a41f#file-index-html-L31

请享用 ;)