2016-07-05 6 views
0

私はすべてのフレームに2つのcss 3d行列を持ち、結果を新しい配列に格納し、その新しい配列を使ってdivのcss3行列変換を更新します。それは最終的には動作しますが、残念ながら予期しない動作が発生しています。それらを掛け合わせることによって、実際にはすべてのフレームで加速されます。したがって、行列の最後の乗算の積は、別の行列などと再び乗算されます。CSS行列を乗算するとアニメーションが加速する

これを解決するにはどうすればよいですか?あなたはfloat精度の問題に入るだろうし、あなたの行列は、おそらく後に解除されますので、あなたのオブジェクトの状態を保存し、それをフレームごとに乗算する行列を使用すべきではありません一般的に

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

各フレームで変数内の変数incをインクリメントしているため、各フレームで回転する回転量が増えているためです。各フレームで、すでに回転を含むstyle属性から現在の行列を取得しています。次に、incをインクリメントしているので、増分を行列内に格納しています。 incであるため、各フレームのインクリメントを効果的に倍増しています。

代わりに、incを一定に保ち、増分しないと正常に動作します。例えば、ここにJSBin

です:http://jsbin.com/doyadakado/edit?html,css,js,output

+0

は、私は複数の変換を望んであれば、聞いてもいいですか? https://jsfiddle.net/testopia/qjfz17g3/28/ – Asperger

+0

複数のもの(2軸の回転など)を1つのトランスフォームにする方が簡単な場合は、最初に両方の回転を計算してから、両方を単一のマトリックス。ここにDOMMatrixポリフィルの一部として書いた関数があります:https://github.com/trusktr/geometry-interfaces/blob/master/src/utilities.js#L93-L112。最初の3つのargはベクトルの方向を定義するために使用され、4つ目のargはそのベクトルの周りに適用したいローテーションです。 – trusktr

+0

私は以下のような関数を使って各軸に回転を適用しています:https://github.com/infamous/infamous/blob/master/src/motor/Node.js#L875-L877基本的には、各軸に回転を適用します。それは単一のマトリックスに適用されます。参考までに、私がpolyfillを実装するために使用したgeometry-interfaces specバージョン1を見ることができます(最新のエディタのドラフトに更新する必要があります)。したがって、あなたの場合は、単一の行列に回転を適用することをお勧めします。 – trusktr

0

多くの乗算。直交軸はもはや直交ではなく、長さが変わる可能性があります。

スケールと回転を浮動小数点として保存し、フレームごとに浮動小数点数を変更し、各フレームから最終行列を作成します。

これは、あなたの正確な問題を解決しない可能性がありますが、それは長期的にあなたを助けると確信しています。