2012-08-03 92 views
5

即时尝试制作一条从左至右穿过画布的线条。 IM尚处于早期阶段,实现这一目标,使用下面的函数来完成一步一步的动画做IM画布:动画贝塞尔曲线绘制

timer = window.setInterval(draw_line, 30); 

我的绘图功能是这样

function draw_line() 
    { 
     context.fillStyle = "#000"; 
     context.fillRect(0, 0, canv.width, canv.height); 

      context.beginPath(); 
     context.lineWidth = 2; 
     context.strokeStyle = '#fff'; 

      //Where p1, p2, cp1, cp2 are point objects that has x & y values already defined  
     context.moveTo(p1.x, p1.y); 
     context.bezierCurveTo(cp1.x,cp1.y,cp2.x,cp2.y,p2.x,p2.y); 
     context.stroke(); 
     context.closePath(); 

      // now i have to move p1, p2 ,cp1,cp2 
      // now here is my problem 
    } 

我明白我需要移动p1.x+= a random number;并且对于cp1和cp2也是一样的,但是关于p2终点它应该按照相同的轨道行!我怎么能做到这一点?

谢谢

回答

4

编辑答案

有了您的澄清,我想我现在适当地可以回答这个问题。

为了让终点跟随起点在画布上的路径,必须存储历史值。在这个例子中,我使用鼠标移动来填充最后16个位置的缓冲区,然后通过遍历RingBuffer在点上形成一条贝塞尔曲线。

function RingBuffer(length) { 
    this.length = length; 
    this.pointer = 0; 
    this.buffer = []; 
} 
RingBuffer.prototype.get = function(index) { 
    if (index < 0) { 
     index += this.length;   
    } 
    return this.buffer[index]; 
} 
RingBuffer.prototype.push = function(value) { 
    this.buffer[this.pointer] = value; 
    this.pointer = (this.length + this.pointer +1) % this.length;  
} 

var c = document.getElementById("myCanvas"); 
var context =c.getContext("2d"); 

timer = window.setInterval(draw_line, 30); 
function Point(x,y) { 
    this.x = x; 
    this.y = y; 
} 
Point.prototype.translateX = function(x) { 
    return this.x += x; 
}; 
Point.prototype.translateY = function(y) { 
    return this.y += y; 
}; 

function draw_line() 
{ 
    context.fillStyle = "#000"; 
    context.fillRect(0, 0, c.width, c.height); 

    var pointer = history.pointer; 
    context.beginPath(); 
    context.lineWidth = 2; 
    context.strokeStyle = '#F00';  
    for (iteration = 0, count = 15; iteration < count; iteration += 3) { 
     var p1 = history.get(--pointer); 
     var p2 = history.get(--pointer); 
     var p3 = history.get(--pointer); 
     var p4 = history.get(--pointer);   

     if (p1 && p2 && p3 && p4) { 

      context.moveTo(p1.x, p1.y); 
      context.bezierCurveTo(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y); 

     } 
     pointer++; 
    } 
    context.stroke(); 
    context.closePath();  

} 

var history = new RingBuffer(16); 
var lastGrab = new Date(); 
c.addEventListener('mousemove', function() { 
    now = new Date(); 
    if (now - lastGrab > 15) { 
     history.push(new Point(event.clientX - c.offsetLeft, event.clientY - c.offsetTop)); 
     lastGrab = now; 
    }  
});​ 

以前的答案左下方,历史的目的。

我不确定我完全理解你想达到的目标,但我认为你所需要做的就是将所有的点数转换为相同的值。这将导致遍历画布的线保持相同的形状。是这样的:

JSFiddle

var c = document.getElementById("myCanvas"); 
var context =c.getContext("2d"); 

timer = window.setInterval(draw_line, 30); 
function Point(x,y) { 
    this.x = x; 
    this.y = y; 
} 
Point.prototype.translateX = function(x) { 
    return this.x += x; 
}; 
Point.prototype.translateY = function(y) { 
    return this.y += y; 
}; 

var p1 = new Point(0,0); 
var p2 = new Point(100,100); 
var cp1 = new Point(15,45); 
var cp2 = new Point(85,45); 

function draw_line() 
{ 
    context.fillStyle = "#000"; 
    context.fillRect(0, 0, c.width, c.height); 

    context.beginPath(); 
    context.lineWidth = 2; 
    context.strokeStyle = '#fff'; 

     //Where p1, p2, cp1, cp2 are point objects that has x & y values already defined  
    context.moveTo(p1.x, p1.y); 
    context.bezierCurveTo(cp1.x,cp1.y,cp2.x,cp2.y,p2.x,p2.y); 
    context.stroke(); 
    context.closePath(); 

    p1.translateX(1); 
    p2.translateX(1); 
    cp1.translateX(1); 
    cp2.translateX(1); 

    if (p1.x > 300) { 
     p1.translateX(-400); 
     p2.translateX(-400); 
     cp1.translateX(-400); 
     cp2.translateX(-400);   
    } 
} 

除非我误解的目标...

+0

谢谢您的回答,但什么即时试图实现的是有尾巴的点。第一个点p1随机移动,第二个点p2跟随p1尾 – trrrrrrm 2012-08-03 15:46:00

+0

有趣的是,我从来没有从你对这个问题的描述中得到这些......不幸的是,我仍然感到困惑。你有什么想要达到的视觉例子吗? – 2012-08-03 15:50:50

+0

@ra_htial你是否正在寻找更像这样的东西? http://jsfiddle.net/mobidevelop/bGgHQ/(在画布上移动鼠标) – 2012-08-03 16:53:58