2012-08-03 151 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