Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何逐步绘制向量路径?(拉斐尔js)_Javascript_Animation_Vector_Svg_Bezier - Fatal编程技术网

Javascript 如何逐步绘制向量路径?(拉斐尔js)

Javascript 如何逐步绘制向量路径?(拉斐尔js),javascript,animation,vector,svg,bezier,Javascript,Animation,Vector,Svg,Bezier,如何以绘制向量路径的方式逐步设置向量路径的动画?换句话说,逐像素缓慢显示路径 我使用的是Raphaël.js,但是如果您的答案不是特定于库的,比如可能有一些通用的编程模式来做这类事情(我对矢量动画相当陌生),那么欢迎您 使用直线路径很容易,就像下面的示例一样: 但是试着改变页面上的代码,比如说,这样:: path("M114 26").animate({path: "M114 26 C 24 23 234 253 234 253"}); 你会明白我的意思。路径当然是从初始状态(点“M114

如何以绘制向量路径的方式逐步设置向量路径的动画?换句话说,逐像素缓慢显示路径

我使用的是
Raphaël.js
,但是如果您的答案不是特定于库的,比如可能有一些通用的编程模式来做这类事情(我对矢量动画相当陌生),那么欢迎您


使用直线路径很容易,就像下面的示例一样:

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

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
怎么能做到这一点。它可以沿路径为对象设置动画,但当对象沿路径设置动画时,如何使该路径逐渐显示自身


解决方案是什么? (Via.)

目前最好的方法似乎是通过使用原始SVG的“假”虚线。有关说明,请参见第4页的或

如何制作渐进式绘图? 我们必须使用
笔划dasharray
笔划dashoffset
并知道要绘制的曲线长度。 此代码在屏幕上不绘制圆、椭圆、多段线、多边形或路径:

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

若动画元素中的“笔划偏移量”(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>


.

你试过拉斐尔的吗?你可以看到它在起作用。

好吧,这是我的想法……解决方案离理想太远了

逐渐显示路径意味着我们应该一点一点地显示它。矢量路径不是由点组成的,而是由曲线组成的,所以在我看来,在矢量图形中没有“自然”的方式来逐渐“绘制”路径。(虽然我对这一点还不太熟悉,可能弄错了。)

唯一的方法是将一条路径转换成若干个点,并逐一显示

目前我的解决方法是绘制一条路径,使其不可见,将其分解为多个子路径,然后逐个显示该子路径


这对拉斐尔来说并不难,但它也不优雅,在大路上走得很慢。不接受我的回答,希望有更好的方法……

不幸的是,正如你似乎同意的那样,在拉斐尔,你可能无法优雅地做到这一点

但是,如果您不需要为这个特定的功能支持IE,那么您可以放弃Raphael API和。然后,也许,你可以装备一辆自行车沿着小路行驶,并以自然的速度显示路线

您可以在IE中优雅地降级,使用Raphael简单地显示路径,而无需动画。

Eureka!(也许——假设你能轻松地走出友好的拉斐尔王国,进入净土……)

您可以使用SVG键时间键样条

下面是一个工作示例:

…下面是一些可能有用的解释:

使用“”属性,我们可以将虚拟长度设置为路径。从那时起,我们可以在“stroke dasharray”中使用此虚拟长度。 因此,如果我们将“路径长度”设置为100个单位,那么我们可以将“stroke dasharray”设置为“50,50”,正好是路径的50%,50%

这种方法有一个问题:唯一支持此属性的浏览器是Opera11


是没有javascript或硬编码长度的平滑曲线drawind动画的示例。(仅适用于Opera 11)

我正是这样做的。我尝试的第一件事是安东的解决方案,但表现糟糕

最后,获得我想要的结果的最简单的方法是对animate函数使用可选的“keyframe”语法

不可见地绘制最终路径,然后在循环中使用getSubpath生成一系列关键帧

创建可见且与第一个关键帧相等的新路径

然后做一些类似的事情:

anmimate({keyFrameObject,timeframe})


对于要绘制的每个像素,不应该都需要关键帧。在反复使用参数后,我发现每个关键帧100px的值对于我试图“绘制”的内容的复杂性/大小起作用。

也许有人在搜索答案,就像我现在已经两天了:

// 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);
    }
});
这对我来说是个好办法,只是用了拉斐尔的方法


下面是注释中要求的JSFIDLE示例,

Anton&Petorpeter的解决方案不幸地在Chrome中因路径变得复杂而崩溃。在链接的演示中,巴士地图很好。查看我创建的动画“花瓣”JSFIDLE,它在FF10和Safari5中绘制正确,但在Chrome中无法控制地闪烁:

(这是全部HTML和内联SVG,没有javascript。)

我仍然在寻找一个非闪存解决方案。动画片很明显不会因为我所做的事情而停止。Raphael.js可以工作,尽管它很快就会变成意大利面


Davidenke,你能用你的解决方案发布一个有效的JSFIDLE吗?我就是不能让它工作。我在Chrome 18中发现一个错误,即使用“.hide”设置为“display:none”的节点没有“getTotalLength”方法。

我想提供一个替代的、Raphael+JS唯一的解决方案,我在自己的工作中大量使用了该解决方案。与davidenke的解决方案相比,它有几个优点:

  • 不在每个循环中清除纸张,使动画路径与其他元素很好地共存
  • 使用Raphael自己的渐进式动画重用单个路径,使动画更加平滑
  • 资源密集程度大大降低
  • 下面是一个方法(可以很容易地重新组合成一个扩展):


    这里有两个在我的网站上使用它的示例:一个用于,另一个用于。

    只是更新一下,你可以试试我创建的
    // 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);
        }
    });
    
    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;
    }
    
    var scribble = new Scribble(paths, {duration: 3000});
    scribble.erase();
    scribble.draw(function () {
        // done
    });