2016-07-05 22 views
0

我有兩個css 3d矩陣,我在每一幀乘,將結果存儲在一個新的數組,並使用該新的數組來更新我的div的css3矩陣轉換。它現在終於有效,但不幸的是我得到了一些意想不到的行爲。作爲將它們相乘的結果,它實際上在每一幀都會加速。所以矩陣的最後乘法的乘積再乘以另一個矩陣,等等。乘以CSS矩陣導致動畫加速

我能做些什麼來解決這個問題?

https://jsfiddle.net/testopia/qjfz17g3/15/

var elem = document.getElementsByTagName("div")[0]; 
var inc = 0; 

var matrix = [3, 0, 0, 0, 
          0, 3, 0, 0, 
       0, 0, 3, 0, 
       0, 0, 0, 1]; 

var matrixLength = matrix.length; 
var request = null; 
var product = []; 

function rotateX() { 
    let deg = inc * (180/Math.PI); 

    let cos = Math.cos(inc); 
    let sin = Math.sin(inc); 

    let x = [1, 0, 0, 0, 
      0, cos, -sin, 0, 
      0, sin, cos, 0, 
      0, 0, 0, 1]; 

    dot(x, matrix); 
    applyTransform(); 
    updateMatrix(); 
    product = []; 
} 

function updateMatrix() { 
    var str = elem.style.transform, 
     stripped = str.substring(str.indexOf("(") + 1, str.length - 1); 

    matrix = stripped.split(", "); 

    for (let i = 0; i < matrixLength; i++) { 
    matrix[i] = parseFloat(matrix[i]); 
    } 
} 

function applyTransform() { 
     elem.style.transform = `matrix3d(${product[0]}, ${product[1]}, ${product[2]}, ${product[3]}, ${product[4]}, ${product[5]}, ${product[6]}, ${product[7]}, ${product[8]}, ${product[9]}, ${product[10]}, ${product[11]}, ${product[12]}, ${product[13]}, ${product[14]}, ${product[15]})`; 
} 

function init() { 
     rotateX(); 
    inc += 0.01; 
    requestAnimationFrame(init); 
} 
init(); 

function dot(rows, columns) { 
    product.push((rows[0] * columns[0]) + (rows[1] * columns[4]) + (rows[2] * columns[8]) + (rows[3] * columns[12])) 
    product.push((rows[0] * columns[1]) + (rows[1] * columns[5]) + (rows[2] * columns[9]) + (rows[3] * columns[13])) 
    product.push((rows[0] * columns[2]) + (rows[1] * columns[6]) + (rows[2] * columns[10]) + (rows[3] * columns[14])) 
    product.push((rows[0] * columns[3]) + (rows[1] * columns[7]) + (rows[2] * columns[11]) + (rows[3] * columns[15])) 

    product.push((rows[4] * columns[0]) + (rows[5] * columns[4]) + (rows[6] * columns[8]) + (rows[7] * columns[12])) 
    product.push((rows[4] * columns[1]) + (rows[5] * columns[5]) + (rows[6] * columns[9]) + (rows[7] * columns[13])) 
    product.push((rows[4] * columns[2]) + (rows[5] * columns[6]) + (rows[6] * columns[10]) + (rows[7] * columns[14])) 
    product.push((rows[4] * columns[3]) + (rows[5] * columns[7]) + (rows[6] * columns[11]) + (rows[7] * columns[15])) 

    product.push((rows[8] * columns[0]) + (rows[9] * columns[4]) + (rows[10] * columns[8]) + (rows[11] * columns[12])) 
    product.push((rows[8] * columns[1]) + (rows[9] * columns[5]) + (rows[10] * columns[9]) + (rows[11] * columns[13])) 
    product.push((rows[8] * columns[2]) + (rows[9] * columns[6]) + (rows[10] * columns[10]) + (rows[11] * columns[14])) 
    product.push((rows[8] * columns[3]) + (rows[9] * columns[7]) + (rows[10] * columns[11]) + (rows[11] * columns[15])) 

    product.push((rows[12] * columns[0]) + (rows[13] * columns[4]) + (rows[14] * columns[8]) + (rows[15] * columns[12])) 
    product.push((rows[12] * columns[1]) + (rows[13] * columns[5]) + (rows[14] * columns[9]) + (rows[15] * columns[13])) 
    product.push((rows[12] * columns[2]) + (rows[13] * columns[6]) + (rows[14] * columns[10]) + (rows[15] * columns[14])) 
    product.push((rows[12] * columns[3]) + (rows[13] * columns[7]) + (rows[14] * columns[11]) + (rows[15] * columns[15])) 
} 

回答

1

這是因爲每個幀都會增加init函數中的inc變量,所以每個幀都會增加每幀所旋轉的旋轉量。在每一幀中,您將獲得style屬性中的當前矩陣(已包含上一次旋轉),然後您將遞增inc,因此您將在矩陣內存儲一個增量,並且還將該增量存儲在內部inc,所以你有效地加倍每幀的增量。

相反,你可以保持inc不變,並且不要增加它,這將起作用。

例如,這裏有一個JSBin:http://jsbin.com/doyadakado/edit?html,css,js,output

+0

請問,如果我想多變換什麼? https://jsfiddle.net/testopia/qjfz17g3/28/ – Asperger

+0

如果您想要應用多個事物(例如在兩個軸上旋轉),可能更容易進行一次變換,然後只需首先計算兩次旋轉,然後應用於單個矩陣。以下是我作爲DOMMatrix填充的一部分編寫的一個函數:https://github.com/trusktr/geometry-interfaces/blob/master/src/utilities.js#L93-L112。前三個參數用於定義矢量的方向,第四個arg是您希望在該矢量周圍應用的旋轉。 – trusktr

+0

我使用如下函數來將旋轉應用於每個軸:https://github.com/infamous/infamous/blob/master/src/motor/Node.js#L875-L877基本上,你看到我了爲每個軸應用旋轉。它被應用於單個矩陣。作爲參考,您可以看到我用來實現polyfill的幾何接口規範版本1(需要更新到最新的編輯器草稿)。所以,就你而言,我建議將旋轉應用於單個矩陣。 – trusktr

0

一般來說,你不應該使用一個矩陣來存儲你的對象狀態,並乘以一幀一幀,因爲你會得到進入float精度問題,你的矩陣後,將突破可能許多乘法。正交軸將不再正交,它們可能會改變它們的長度。

只需將您的縮放和旋轉存儲爲浮動,每幀修改這些浮動,然後從每個幀中爲它們構建最終矩陣。

這可能無法解決您確切的問題,但我相信它會幫助您從長遠來看。