Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
297 views
in Technique[技术] by (71.8m points)

javascript - How to draw a vector path progressively? (Raphael.js)

How to animate a vector path like it's being drawn, progressively? In other words, slowly show the path pixel by pixel.

I'm using Rapha?l.js, but if your answer is not library specific—like maybe there's some general programming pattern for doing that kind of thing (I'm fairly new to vector animation)—it's welcome!


It's easy to do with straight paths, as easy as an example on that page::

path("M114 253").animate({path: "M114 253 L 234 253"});

But try to change code on that page, say, this way::

path("M114 26").animate({path: "M114 26 C 24 23 234 253 234 253"});

And you'll see what I mean. Path is certainly animated from it initial state (point "M114 26") to the end state (curve "C 24 23 234 253 234 253" starting on point "M114 26"), but not in a way specified in question, not like it's being drawn.

I don't see how animateAlong can do that. It can animate an object along a path, but how can I make this path to gradually show itself while object is being animated along it?


The solution?

(Via peteorpeter's answer.)

Seems like currently the best way to do it is via 'fake' dashes using raw SVG. For the explanation see this demo or this document, page 4.

How produce progressive drawing?

We have to use stroke-dasharray and stroke-dashoffset and know length of curve to draw. This code draw nothing on screen for circle, ellipse, polyline, polygone or path:

<[element] style="stroke-dasharray:[curve_length],[curve_length]; stroke-dashoffset:[curve_length]"/>

If in animate element stroke-dashoffset decrease to 0, we get progressive drawing of curve.

<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>

If you know a better way, please leave an answer.


Update (26 Apr. 2012): Found an example that illustrates the idea well, see Animated Bézier Curves.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Maybe someone is searching for an answer, like me for two days now:

// 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);
    }
});

That did the trick for me, only by using RaphaelJS methods.

Here is a jsFiddle example as requested in the comments, http://jsfiddle.net/eA8bj/


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...