2011-05-20 23 views
1

我想創建一個可視化繪製立方貝塞爾曲線的畫布腳本,但到目前爲止,我一直不成功讓我的線連接。見代碼爲什麼我的畫布JavaScript不能連線?

var canvas=document.getElementById("canvas"); 
var c = canvas.getContext("2d"); 
    // Bezier eq. code 
coord = function(x,y) { if(!x) var x=0; if(!y) var y=0; return {x: x, y: y}; } 

B1 = function(t) { return (t*t*t); } 
B2 = function(t) { return (3*t*t*(1-t)); } 
B3 = function(t) { return (3*t*(1-t)*(1-t)); } 
B4 = function(t) { return ((1-t)*(1-t)*(1-t)); } 

function getBezier(t,C1,C2,C3,C4) { 
    var pos = new coord(); 
    pos.x = C1.x * B1(t) + C2.x * B2(t) +C3.x * B3(t) + C4.x * B4(t); 
    pos.y = C1.y * B1(t) + C2.y * B2(t) + C3.y * B3(t) + C4.y * B4(t); 
    return pos; 
} 
//Ctrl points. 
P1 = coord(12,12); 
P2 = coord(90,1); 
P3 = coord(0,190); 
P4 = coord(150,150); 


t=0; 
function drawbez() { 
    if (t == 0) {var interval = setInterval('drawbez()',1);} 
    var curpos = getBezier(t2,P1,P2,P3,P4); // Staðan í ferlinum 
    if (t > 1) { clearInterval(interval); return; } 
    c2.moveTo(curpos.x,curpos.y); 
    c2.lineTo(curpos.x+t2,curpos.y+t2); 
    c2.stroke(); 
    t = t+0.01 
} 

任何想法?

我做了一個使用完全相同的繪圖命令,並使用隨機數的代碼,實際上給了我連線。

對HTML

見代碼here

使用貝塞爾曲線從13日並行 http://13thparallel.com/archive/bezier-curves/

回答

1

嘿,我把它改變你的代碼如下工作:

var canvas = document.getElementById("canvas"); 
var c = canvas.getContext("2d"); 
// Bezier eq. code 
coord = function(x, y) { 
    if (!x) { 
     x = 0; 
    } 
    if (!y) { 
     y = 0; 
    } 
    return { 
     x: x, 
     y: y 
    }; 
}; 

B1 = function(t) { 
    return (t * t * t); 
}; 
B2 = function(t) { 
    return (3 * t * t * (1 - t)); 
}; 
B3 = function(t) { 
    return (3 * t * (1 - t) * (1 - t)); 
}; 
B4 = function(t) { 
    return ((1 - t) * (1 - t) * (1 - t)); 
}; 

function getBezier(t, C1, C2, C3, C4) { 
    var pos = new coord(); 
    pos.x = C1.x * B1(t) + C2.x * B2(t) + C3.x * B3(t) + C4.x * B4(t); 
    pos.y = C1.y * B1(t) + C2.y * B2(t) + C3.y * B3(t) + C4.y * B4(t); 
    return pos; 
} 
//Ctrl points. 
P1 = coord(12, 12); 
P2 = coord(90, 1); 
P3 = coord(0, 190); 
P4 = coord(150, 150); 

t = 0; 

var drawbez = function() { 
    var interval; 
    if (t === 0) { 
     interval = setInterval(drawbez, 1); 
    } 
    var curpos = getBezier(t, P1, P2, P3, P4); // Staðan í ferlinum 
    if (t > 1) { 
     if (interval) { 
      clearInterval(interval); 
     } 
     return; 
    } 
    //c.moveTo(curpos.x, curpos.y); 
    c.lineTo(curpos.x + t, curpos.y + t); 
    c.stroke(); 
    t = t + 0.01; 
}; 

drawbez(); 

請參閱this fiddle的工作示例。

基本上,t2從未宣稱,interval是超出範圍,則setTimeout()參考drawbez似乎是超出範圍(可能是因爲您指定的字符串函數的名稱,而不是直接對象引用),除去.moveTo()爲約翰格林的回答中提到了一條更平滑的路線。

+1

快速提示...間隔仍然超出範圍。它應該是一個全球性的,因爲你會檢查每次你回來。 – 2011-05-20 11:37:53

+0

@John - 好點,是的,它應該在'drawbez()'函數之外聲明。 :) – 2011-05-20 11:40:13

0

教程中,我覺得你有一些較大的問題,您的貝塞爾(了lineTo而不是bezierCurveTo甚至到quadraticCurveTo),但斷開線條是因爲你在繪製之間移動光標。註釋掉這一行:

c2.moveTo(curpos.x,curpos.y); 

或者,可能更準確:早期而論道的

c2.lineTo(curpos.x, curpos.y); // remove the moveTo. 

而且,部分原因是因爲有人指責我(確實如此)......我不建議畫布繪製曲線。基礎架構完全是程序化的,這可能意味着數以千計的DOM繪圖調用即使是非常簡單的圖像。除非你需要僞3D仿射矩陣或類似的東西,否則SVG通常更好。

0

你的邏輯不太對。你的代碼不斷繪製一條從curpos到curpos + t2的線,因爲在你調用clearinterval之前,t2總是在一條線之下。我已經調整了下面的代碼,它存儲了prevcoord,並在每次drawBez被調用時從前一個coord到新coord繪製一條線。

如果你打算在畫布上做有效的動畫,這絕對不是最好的方法。嘗試搜索創建動畫流程的最佳實踐(繪製更新回憶等)。

var canva2s=document.getElementById("canvas2"); 
    var c2 = canvas2.getContext("2d"); 
    c2.lineWidth = 1; 
    // Bezier jafna sett inn 
    coord = function(x,y) { 
     if(!x) var x=0; 
     if(!y) var y=0; 
     return { 
      x: x, 
      y: y 
     }; 
    } 

    B1 = function(t) { 
     return (t*t*t); 
    } 
    B2 = function(t) { 
     return (3*t*t*(1-t)); 
    } 
    B3 = function(t) { 
     return (3*t*(1-t)*(1-t)); 
    } 
    B4 = function(t) { 
     return ((1-t)*(1-t)*(1-t)); 
    } 

    function getBezier(t,C1,C2,C3,C4) { 
     var pos = new coord(); 
     pos.x = C1.x * B1(t) + C2.x * B2(t) +C3.x * B3(t) + C4.x * B4(t); 
     pos.y = C1.y * B1(t) + C2.y * B2(t) + C3.y * B3(t) + C4.y * B4(t); 
     return pos; 
    } 
    //Stýripunktar 
    P1 = coord(12,12); 
    P2 = coord(90,1); 
    P3 = coord(0,190); 
    P4 = coord(150,150); 

    //var newpos = getBezier(0.2,P1,P2,P3,P4); 
    t2=0; 
    var prevCoord = null; 
    //dir=0; 
    function drawbez() { 
     if (t2 == 0) { 
      var interval = setInterval('drawbez()',1); 
     }   
     var curpos = getBezier(t2,P1,P2,P3,P4); // Staðan í ferlinum   
     if (t2 > 1) { 
      clearInterval(interval); 
      return; 
     }   
     if(prevCoord != null){ 
      c2.moveTo(prevCoord.x,prevCoord.y); 
      c2.lineTo(curpos.x,curpos.y); 
      c2.stroke(); 
     }   
     prevCoord = curpos;    
     t2 = t2+0.01; 
    } 
相關問題