2012-08-03 10 views
5

Próbuję utworzyć linię przechodzącą przez płótno od lewej do prawej. im wciąż na wczesnym etapie, aby osiągnąć to, aby zrobić to im przy użyciu następujących funkcji, aby wykonać krok po animacji krokuObszar roboczy: Animowany rysunek krzywa beziera

timer = window.setInterval(draw_line, 30); 

moja funkcja rysunek jest jak ten

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 
    } 

Rozumiem, że muszę przenieść p1.x+= a random number;, a także to samo dla cp1 i cp2, ale co z p2 Punkt końcowy powinien podążać linii tej samej ścieżki! jak mogę to osiągnąć?

Dziękuję

Odpowiedz

4

odpowiedź Edited

Dzięki swojej wyjaśnienia, myślę, że mogę odpowiedzieć na to odpowiednio teraz.

Aby punkt końcowy podążał wzdłuż ścieżki, punkt początkowy przechodził przez płótno, należy zapisać wartości historyczne. W tym przykładzie, http://jsfiddle.net/mobidevelop/bGgHQ/, używam ruchów myszki, aby wypełnić bufor z ostatnich 16 pozycji, a następnie użyć tej krzywej by utworzyć krzywą Beziera przez punkty poprzez iterację nad 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; 
    }  
});​ 

Poprzednia odpowiedź lewo poniżej, dla celów historycznych.

Nie jestem pewien, czy całkowicie rozumiem, co próbujesz osiągnąć, ale myślę, że wszystko, co musisz zrobić, to przetłumaczyć wszystkie swoje punkty według tej samej wartości. To spowoduje, że linia będzie przecinać płótno zachowując ten sam kształt. coś takiego:

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);   
    } 
} 

Chyba jestem nieporozumienie cel ...

+0

Dziękuję za odpowiedź, ale co im próbuje osiągnąć to punkt, który ma ogon. pierwszy punkt p1 porusza się w przypadkowym kierunku, a drugi punkt p2 podąża za ogonem p1. – trrrrrrm

+0

Ciekawe, nigdy bym tego nie zrobił z twojego opisu problemu ... I niestety wciąż jestem zdezorientowany. Czy masz wizualny przykład tego, co chcesz osiągnąć? –

+0

@ra_htial czy szukasz czegoś więcej? http://jsfiddle.net/mobidevelop/bGgHQ/ (Przesuń myszką po płótnie) –

Powiązane problemy