如何在html5画布中逐步绘制线条动画

Posted

技术标签:

【中文标题】如何在html5画布中逐步绘制线条动画【英文标题】:How to progressively draw line animation in html5 canvas 【发布时间】:2014-10-18 06:49:48 【问题描述】:

我正在使用画布。我已经画了一组线。这是我的示例代码

for(var i = 0 ; i< points.length; i++)
var point = points[i];

setInterval(function() 
  ctx.strokeStyle = "black";
  ctx.moveTo(point.startX, point.startY);
  ctx.lineTo(point.startX1, point.startY1); 
  ctx.stroke();
 , 500);​

此代码每 0.5 秒绘制一次线。但我希望逐步对其进行动画处理。 所以请帮助逐步画线。

此屏幕截图显示了输出。我在 SVG 中实现了这一点。但我在画布上也需要同样的东西。

【问题讨论】:

语句末尾的数字 500 表示函数重复的时间间隔(以毫秒为单位)。尝试输入一个较小的数字(甚至只有 1 个),这可能会奏效。 是的@NDraskovic。但是动画的持续时间减少了。 :(所以如果可能的话,建议其他方式 您可能需要对动画的参数进行试验,我的建议是减少时间间隔,但也要减少在该间隔内绘制的线的长度。这样,您将有效地延长动画。从您发布的代码中,我认为这意味着在 points[] 数组中添加更多点 看看这个html5canvastutorials.com/advanced/…,它的功能与您需要的类似(第 30-51 行),您只需省略清除先前状态的部分 感谢 NDraskovic 希望这会有所帮助.. 【参考方案1】:
<!DOCTYPE html>
<html>
    <head>
        <title>Parent selector</title>
    </head>
<body>
<canvas   id="canva"></canvas>
<script>
    var canva = document.getElementById('canva'),
        ctx = canva.getContext('2d');

    var Point = function (x, y) 
        this.startX = x;
        this.startY = y;
    ;
    var points = [new Point(1, 2), 
                  new Point(10, 20), 
                  new Point(30, 30), 
                  new Point(40, 80), 
                  new Point(100, 100), 
                  new Point(120, 100)];

    //goto first point
    ctx.strokeStyle = "black";
    ctx.moveTo(points[0].startX, points[0].startY);

    var counter = 1,
    inter = setInterval(function() 
        //create interval, it will
        //iterate over pointes and when counter > length
        //will destroy itself
        var point = points[counter++];
        ctx.lineTo(point.startX, point.startY); 
        ctx.stroke();
        if (counter >= points.length) 
           clearInterval(inter);
        
        console.log(counter);
    , 500);
    ctx.stroke();
</script>
    </body>
</html>

【讨论】:

嗨对不起.. :(这就是我的代码所做的。画一条线,500ms延迟后画另一条线等等..但我需要像屏幕截图一样渐进式。你能建议如果可能的话还有其他方法吗?? 见更新。没有背景和其他功能。但它逐渐绘制图表。请提供更详细的问题。 是的。正如我所提到的,它是使用 jquery 的 animate 方法在 SVG 中生成的。除了setInterval之外,我需要任何其他带来这个o / p的方法。仅供参考,背景不重要。我只说线路。谢谢。【参考方案2】:
async function aWaitF(ctx, index, ary) 

        if (!ary) return;

        for (let i = 0; i < ary.length; i++) 

            let cur = ;
            cur.x = name_pos[i].x;  // x position
            cur.val = ary[i].Y - 0;
            cur.y = y_h - y_h * ((ary[i].Y - 0) / series_max); // y position
            let prev = ;
            let next = ;
            let font_pos = null;

            if (i === 0) 

             else 
                prev.val = ary[i - 1].Y - 0;
                prev.x = name_pos[i - 1].x;
                prev.y = t + y_h - y_h * ((ary[i - 1].Y - 0) / series_max);
                next.val = ary[i + 1] ? ary[i + 1].Y - 0 : 0;
                ctx.lineWidth = 0.5;

                **await orderRender();**

                function orderRender() 
                    return new Promise(resolve => 
                        let w = cur.x - prev.x;
                        let h = cur.y - prev.y;
                        **let rad = Math.atan2(h, w);** 

                        let x = cur.x > prev.x ? prev.x : cur.x;
                        let y = cur.y > prev.y ? prev.y : cur.y;
                        **let imgData = ctx.getImageData(x, y, w, h);**


                        let timer = requestAnimFrame(drawLine);
                        let num = 0;

                        function drawLine() 
                            **ctx.putImageData(imgData, x, y);**
                            ctx.beginPath();
                            ctx.moveTo(prev.x, prev.y);
                            let newX = prev.x + num;
                            let newH = Math.tan(rad) * num;
                            let newY = prev.y + newH;
                            // num += (ary.length - i) * 10;
                            num += 5;

                            ctx.lineTo(newX, newY);
                            ctx.stroke();
                            timer = requestAnimFrame(drawLine);
                            if (num >= w) 
                                ctx.beginPath();
                                ctx.moveTo(prev.x, prev.y);
                                ctx.lineTo(cur.x, cur.y);
                                ctx.stroke();
                                window.cancelAnimationFrame(timer);
                                resolve();
                            
                        
                    );
                
            
        
    

【讨论】:

以上是关于如何在html5画布中逐步绘制线条动画的主要内容,如果未能解决你的问题,请参考以下文章

在画布上创建线条动画

在 HTML5 画布上动画绘制路径

案例 HTML5 Canvas流动线条动画特效

HTML5绘制3D线条延伸动画特效

在画布 (HTML5) 上绘制好看的(如在 Flash 中)线条 - 可能吗?

在画布中使用形状制作动画线条