2015-10-21 128 views
0

我正在試圖讓如何繪製在HTML5對象時,但在信息的多個不同來源找到了不同的解釋已經引起了一些混亂做矩陣變換的理解。我發現信息說,爲了在html5中創建繪製對象的動畫,如here所示,同時我也看到可以通過轉換繪製的點將變換應用於頁面上的單個對象,但我不確定它是如何實現的作品。功能HTML5矩陣變換

我發現,實現腿的動畫(兩行)代碼示例,但它確實動畫不施加轉換到帆布,使用用於在某些其他文件中定義的變換矩陣的功能對象。該代碼提供了自己的實現moveTo()lineTo()(通常與畫布對象一起使用),在該實現中,它轉換傳入的點,根據視口重新調整其位置,然後調用畫布的移動版本以傳遞轉化點。

所以這裏有幾點困惑: 1.當setTransform()只能在畫布上使用時,在變換矩陣對象上實現新的變換函數的目的是什麼? 2.方法如rotate()translate()在矩陣對象上被調用而沒有傳入點,所以這些操作如何實際應用? 3.什麼時候應該將轉換應用於整個畫布(如所提供的鏈接所做的那樣),而不是繪製特定的對象,因爲它們似乎都可以工作?

我一般只是尋找相關的一般概述,我相當困惑是如何工作的。從該示例中的代碼是下面供參考:

<head> 
<script src=g.js></script> 
<script src=matrix4x4.js></script> 
</head> 
<body onload=g_start()> 
<canvas id=myCanvas1 width=480 height=480></canvas> 
<script> 
    var w, h, g; 

    function viewport(p) { 
     return [ w/2 * p[0] + w/2, h/2 - p[1] * w/2 ]; 
    } 

    function moveTo(p) { 
     var q = m.transform(p); // APPLY 3D MATRIX TRANFORMATION 
     var xy = viewport(q); // APPLY VIEWPORT TRANSFORM 
     g.moveTo(xy[0], xy[1]); 
    } 

    function lineTo(p) { 
     var q = m.transform(p); // APPLY 3D MATRIX TRANFORMATION 
     var xy = viewport(q); // APPLY VIEWPORT TRANSFORM 
     g.lineTo(xy[0], xy[1]); 
    } 

    myCanvas1.animate = function(_g) { 
     g = _g; 
     w = g.canvas.width; 
     h = g.canvas.height; 

     g.fillStyle = 'rgb(200,140,255)'; 
     g.beginPath(); 
     g.moveTo(0, 0); 
     g.lineTo(w, 0); 
     g.lineTo(w, h); 
     g.lineTo(0, h); 
     g.lineTo(0, 0); 
     g.stroke(); 

     g.fillStyle = 'rgb(128,0,0)'; 
     g.strokeStyle = 'rgb(0,0,0)'; 

     var legBend = .4; 

     var t = 3 * time; 

     for (var leg = 0 ; leg < 2 ; leg++) { 
    var angle = -Math.PI/2 * (1 + Math.sin(time)); 
    console.log(angle); 
     var sign = (leg == 0) == (angle < -Math.PI/2) ? -1 : 1; 

     m.identity(); 
     m.rotateY(-Math.PI/2 * (1 + Math.sin(time))); 

     g.beginPath(); 

     m.translate(0, .5, .1 * sign); 
     moveTo([0,0,0]);    // HIP 

     m.rotateZ(-.5 * legBend + sign * legBend * Math.cos(t)); 

     m.translate(0, -.5, 0); 

     lineTo([0,0,0]);    // HIP 

     m.rotateZ(2 * legBend + 2 * legBend * sign * Math.sin(t)); 
     m.translate(0, -.5, 0); 
     lineTo([0,0,0]);    // KNEE 

     m.translate(-.1, 0, 0); 
     lineTo([0,0,0]);    // KNEE 

     g.strokeStyle = 'rgb(0,0,0)'; 
     g.lineWidth = 30; 
     g.stroke(); 

     g.strokeStyle = 'rgb(255,0,0)'; 
     g.lineWidth = 20; 
     g.stroke(); 
     } 
    } 

</script> 
</body> 
+2

它讓我在身體上感到痛苦,因爲看不到'src = g.js'的引號。 –

回答

1

重要HTML5畫布變換概念:

  • 所有畫布的轉化方法(以及.transform)操作相對於當前畫布起源和該原點給出座標[0,0]。起始原點位於畫布的左上角。 .setTransform將重置當前畫布原點,然後進行相對於該重置原點的轉換。

  • 轉換不影響現有圖紙。所以fillRect(0,0)跟隨translate(5,0)不會移動已經繪製的矩形。現有的矩形仍將顯示在畫布的左上角。

  • 轉換會影響新的圖紙。

  • translate方法由指定的x,y的距離移動至原點。因此,translate(5,0)將使畫布繪製原點[0,0]從畫布左側起5個像素。因此,translate(5,0)後跟fillRect(0,0)會導致新的矩形在畫布左側顯示5個像素。

  • 變換實際平移(移動),旋轉,縮放整個畫布繪製表面。所以新圖紙不會單獨移動,旋轉或縮放。 由於整個畫布繪圖表面已被移動,旋轉或縮放,所以新繪圖出現移動,旋轉或縮放。

  • 轉型是累積的。所以如果你翻譯(5,0)然後翻譯(0,50),畫布原點[0,0]將在左邊5像素和頂部50像素。所以fillRect(0,0)將會從左邊算起5個像素,從頂部算起50個像素。

因此,要回答你的問題:因爲變革是累積

  1. 順序轉換是有用的。因此,爲了使人形象「移動」,您可以使用轉換的累積效果,而不必記住他們的最後位置或不必計算他們的新位置。

    // the person image will move across the canvas in 5px increments over time 
    // No need to remember its last location 
    // No need to calculate its new position 
    // That's because the canvas internally remembers & calculates its own origin. 
    for(var i=0;i<20;i++){ 
        context.clearRect(0,0,canvas.width,canvas.height); 
        context.translate(5,0); 
        context.drawImage(person,0,0); 
        // wait 1 second 
    } 
    
  2. 由於所有的轉變是相對於當前畫布原點座標,你不必重新指定座標任何轉化方法 - 畫布「記住」它的當前原點爲您服務。

  3. 單個畫布圖不受轉換的影響。轉換將整個畫布和新圖畫移動到「一起去」。任何在轉換之前存在的圖紙都不會受到後續轉換的影響 - 預先存在的圖紙仍然完全保留在第一次繪製的位置。

+0

感謝您的回答!所以你說任何時候你在做html5轉換時,你只能將轉換應用到整個canvas而不是特定的對象(即不使用''setTransform()''')?在我看來,在這個例子中,''''''''''''函數可能會應用它自己的一種不使用''setTransform()''''的轉換,因爲該函數只適用於2D這個程序正在使用3d。 – loremIpsum1771

+0

此外,如果使用'''setTransform()'''是實現'''Transform()'''方法的唯一方法,那麼你怎樣才能使用它的3D形狀,B/C我目前正在使用jQuery使用'''canvas.getContext(「2d」)'''獲取上下文,但是我不知道是否有方法在3d中執行此操作。 – loremIpsum1771