簡體   English   中英

如何逐步繪制矢量路徑? (Raphael.js)

[英]How to draw a vector path progressively? (Raphael.js)

如何為矢量路徑設置動畫,就像它正在逐漸被繪制一樣? 換句話說,逐個像素地慢慢顯示路徑。

我正在使用Raphaël.js但是如果你的答案不是特定於庫的 - 就像有一些通用的編程模式來做那種事情(我對矢量動畫很新) - 非常歡迎!


使用直線路徑很容易,就像該頁面上的示例一樣簡單::

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

但嘗試改變該頁面上的代碼,比如說,這樣::

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

你會明白我的意思。 從初始狀態(點“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]"/> 

如果在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> 

如果你知道更好的方法,請留下答案。


更新 (2012年4月26日):找到一個很好地說明這個想法的例子,參見AnimatedBézierCurves

也許有人正在尋找答案,就像我現在兩天一樣:

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

這對我來說只是通過使用RaphaelJS方法。

這是評論中要求的jsFiddle示例, http://jsfiddle.net/eA8bj/

找到了! (也許 - 假設你在拉斐爾的友好領域之外走進純凈的SVG土地......)

您可以使用SVG keyTimeskeySplines

這是一個有效的例子:

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

......這里有一些可能有用的解釋:

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

我想提供一個替代的,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;
}

以下是我網站上使用的兩個示例:一個用於路徑轉換 ,另一個用於漸進式刻字

使用“ pathLength ”屬性,我們可以將虛擬長度設置為路徑。 從那時起,我們可以在“stroke-dasharray”中使用這個虛擬長度。 因此,如果我們將“pathLength”設置為100個單位,那么我們可以將“stroke-dasharray”設置為“50,50”,這將是50%,50%的路徑!

這種方法存在一個問題:唯一支持此屬性的瀏覽器是Opera 11。

是沒有javascript或硬編碼長度的平滑曲線drawind動畫的示例。(僅在Opera 11中正常工作)

我已經為此創建了一個腳本: Scribble.js ,基於這個偉大的dasharray/dashoffset技術

只需在一堆SVG <path>實例化它:

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

-

注意:完整的USAGE代碼: https//gist.github.com/abernier/e082a201b0865de1a41f#file-index-html-L31

請享用 ;)

當路徑變得復雜時,Anton&Peteorpeter的解決方案可能會在Chrome中崩潰。 這個鏈接演示中的公交地圖很好。 看看我創建的動畫“花瓣”jsfiddle,它在FF10和Safari5中正確繪制,但在Chrome中無法控制地閃爍:

http://jsfiddle.net/VjMvz/

(這是所有HTML和內聯SVG,沒有javascript。)

我仍在為此尋找非Flash解決方案。 AnimateAlong顯然不會因為我正在做的事而削減它。 Raphael.js可以工作,雖然它可能會很快變成回調意大利面。

Davidenke,你能發布一個有效的解決方案嗎? 我無法讓它發揮作用。 我在Chrome 18中收到一個錯誤,即使用“.hide”設置為“display:none”的節點沒有方法'getTotalLength'。

不幸的是,正如你似乎同意的那樣,你可能無法在拉斐爾中做到這一點。

但是 ,如果通過%deity%的某個筆划,您不需要支持IE用於此特定功能,則可以放棄Raphael API並直接操作SVG 然后,也許,你可以裝備一個面具沿着路徑騎行並以自然的速度展示線條。

您可以在IE中優雅地降級,只需使用Raphael顯示路徑,而無需動畫。

只需對此進行更新,您就可以嘗試使用Lazy Line Painter

我正是這樣做的。 我嘗試的第一件事是安東的解決方案,但性能很糟糕。

最后,獲得我想要的結果的最簡單方法是為animate函數使用替代的“keyframe”語法。

無形地繪制最終路徑,然后在循環中使用getSubpath生成一大堆關鍵幀。

創建一個可見且等於第一個關鍵幀的新路徑。

然后做類似的事情:

path.anmimate({keyFrameObject,timeframe});

您不應該為要繪制的每個像素都使用關鍵幀。 在玩完參數后,我發現每個關鍵幀的值為100px,因為我試圖“繪制”的復雜性/大小

你有沒有試過拉斐爾的動畫片 您可以在演示頁面上看到它的運行情況。

好吧,這是我對此的看法......解決方案離理想太遠了。

逐漸顯示路徑意味着我們應該逐點顯示它。 矢量路徑不是由點組成,而是由曲線組成,所以在我看來,沒有“自然”的方法可以逐漸“繪制”矢量圖形中的路徑。 (雖然我對此很新,可能會弄錯。)

唯一的方法是以某種方式將路徑轉換為多個點並逐個顯示它們。

目前我的解決方法是繪制路徑,使其不可見,將其分解為多個子路徑,並逐個顯示子路徑。

這對拉斐爾來說並不難,但它也不優雅,而且在很大的路徑上也很慢。 不接受我的回答,希望有更好的方法......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM