2013-01-23 94 views
5

我有一堆点,我想慢慢绘制。我尝试setTimeOut和从这个tutorial的影响。但没有那么多成功。如何使用画布动画绘制曲线?

的功能看起来像这样

功能:

var myFunction = function(ctx, grid, points) { 
       ctx.beginPath(); 
       ctx.moveTo(points[0].x, points[0].y); 
       ctx.lineWidth = 2; 
       ctx.strokeStyle = '#2068A8'; 
       ctx.fillStyle = '#2068A8'; 
       var count = 1; 
       for (count = 1; count < points.length; count++) { 
        ctx.lineTo(points[count].x , points[count].y); 
       } 
       ctx.stroke(); 
      } 

围绕这个功能有没有很多其他的绘图功能,但我只是想只有一个动画。

我怎样才能缓慢画一个功能的画布?

+0

你提供流畅的线条我们演示了迄今为止所做的一切:http://jsfiddle.net/ –

+0

好吧!我希望我可以......只需在图形上绘制两条线,并且应该用几个点绘制一条线。我只是想动画,通过几个点画。 Thx – trouble

回答

9

有两种方法可以做到这一点,我可以从头顶上想到这些。一个基本上是绘制一个点,并在绘制另一个点之前暂停一段时间。这是我提供的第一个例子。第二种方法是将局部线条绘制到当前目标上,这样可以获得更平滑的绘图外观。作为一个附注,我在这两个示例中都使用了requestAnimationFrame,它是推荐的做任何类型的画布动画的方法。

var canvas = document.getElementById("canvas"), 
    ctx = canvas.getContext("2d"); 

canvas.width = 400; 
canvas.height = 200; 

var points = [], 
    currentPoint = 1, 
    nextTime = new Date().getTime()+500, 
    pace = 200; 

// make some points 
for (var i = 0; i < 50; i++) { 
    points.push({ 
     x: i * (canvas.width/50), 
     y: 100+Math.sin(i) * 10 
    }); 
} 

function draw() { 

    if(new Date().getTime() > nextTime){ 
     nextTime = new Date().getTime() + pace; 

     currentPoint++; 
     if(currentPoint > points.length){ 
      currentPoint = 0; 
     } 
    } 
    ctx.clearRect(0,0,canvas.width, canvas.height); 
    ctx.beginPath(); 
    ctx.moveTo(points[0].x, points[0].y); 
    ctx.lineWidth = 2; 
    ctx.strokeStyle = '#2068A8'; 
    ctx.fillStyle = '#2068A8'; 
    for (var p = 1, plen = currentPoint; p < plen; p++) { 
     ctx.lineTo(points[p].x, points[p].y); 
    } 
    ctx.stroke(); 

    requestAnimFrame(draw); 
} 

draw(); 

Live Demo

如果您发现是有些不连贯,你可以做以下让正在制定

var canvas = document.getElementById("canvas"), 
    ctx = canvas.getContext("2d"); 

canvas.width = 400; 
canvas.height = 200; 

var points = [], 
    currentPoint = 1, 
    speed = 2, 
    targetX = 0, 
    targetY = 0, 
    x = 0, 
    y = 0; 

// make some points 
for (var i = 0; i < 50; i++) { 
    points.push({ 
     x: i * (canvas.width/50), 
     y: 100+Math.sin(i) * 10 
    }); 
} 

// set the initial target and starting point 
targetX = points[1].x; 
targetY = points[1].y; 
x = points[0].x; 
y = points[0].y; 

function draw() { 
    var tx = targetX - x, 
     ty = targetY - y, 
     dist = Math.sqrt(tx*tx+ty*ty), 
     velX = (tx/dist)*speed, 
     velY = (ty/dist)*speed; 

     x += velX 
     y += velY; 

    if(dist < 1){ 
     currentPoint++; 

     if(currentPoint >= points.length){ 
      currentPoint = 1; 
      x = points[0].x; 
      y = points[0].y; 
     } 

     targetX = points[currentPoint].x; 
     targetY = points[currentPoint].y; 
    } 

    ctx.clearRect(0,0,canvas.width, canvas.height); 
    ctx.beginPath(); 
    ctx.moveTo(points[0].x, points[0].y); 
    ctx.lineWidth = 2; 
    ctx.strokeStyle = '#2068A8'; 
    ctx.fillStyle = '#2068A8'; 

    for (var p = 0, plen = currentPoint-1; p < plen; p++) { 
     ctx.lineTo(points[p].x, points[p].y); 
    } 
    ctx.lineTo(x, y);  
    ctx.stroke(); 

    requestAnimFrame(draw); 
} 

draw(); 

Live Demo

+1

这真的很不错!好工作Loktar! :) – trouble

+0

但一个问题如何在绘制结束时停止动画? – trouble

+2

我的不好只是删除'currentPoint = 0;' – trouble