Html CSS transform matrix3d 3D轉場特效


Html CSS transform matrix3d 3D轉場特效

透視矩陣

       2n/(r-l)    0      (r+l)/(r-l)    0
         0      2n/(t-b)  (t+b)/(t-b)    0
         0         0      (n+f)/(n-f) 2fn/(n-f)
         0         0          -1         0

t、b、l、r 分別代表camera投影面的上下左右,camera指向-z方向(指向屏幕內),n為近景距離,f為遠景距離。

Y軸旋轉矩陣

            cos(θ)  0  sin(θ)  0
              0     1    0     0
           -sin(θ)  0  cos(θ)  0
              0     0    0     1

轉場效果


主要步驟:

    let w = 1024;
    let h = 576;
    // 1/2寬作為近景在 X-O-Z 平面上,可以剛好使圖像左右兩邊到camera的夾角為直角,
    // 且3個點組成的三角形為等腰直角三角形,便於后面計算。
    let n = -w / 2;
    let f = -w * 1000;

    let r = 1;
    let l = -1;
    let t = 1;
    let b = -1;

    let m00 = 2 * n / (r - l);
    let m02 = (r + l) / (r - l); //0
    let m11 = 2 * n / (t - b);
    let m12 = (t + b) / (t - b); //0
    let m22 = (n + f) / (n - f);
    let m23 = 2 * f * n / (n - f);
    let m32 = -1;

    const aperspect = math.matrix([
        [m00, 0, m02, 0],
        [0, m11, m12, 0],
        [0, 0, m22, m23],
        [0, 0, m32, 0]
    ])
    const aperspectT = math.transpose(aperspect);

    var change3d = (rfactor, dfactor, mSlide) => {
        //thet θ,圖像距離近景越近,圖像完全移出畫布的角度越逼近於90度,越遠越接近45度。
        let thet = 1 / 2 * rfactor * Math.PI;
        const rotationYT = math.matrix([
            [Math.cos(thet), 0, -Math.sin(thet), 0],
            [0, 1, 0, 0],
            [Math.sin(thet), 0, Math.cos(thet), 0],
            [0, 0, 0, 1]
        ])
        let result = math.identity(4);
        //把圖像移動至原點(0, 0),方便計算繞Y軸旋轉
        //若拉遠至近景距離的2倍,視覺上為圖像縮小1倍
        const transOT = math.matrix([
            [1, 0, 0, 0],
            [0, 1, 0, 0],
            [0, 0, 1, 0],
            [-w / 2, -h / 2, -w / 2 * dfactor, 1]
        ]);
        result = transOT;
        //y旋轉
        result = math.multiply(result, rotationYT);
        //透視
        result = math.multiply(result, aperspectT);
        //還原至畫布中央
        const transCenterT = math.matrix([
            [1, 0, 0, 0],
            [0, 1, 0, 0],
            [0, 0, 1, 0],
            [w / 2, h / 2, 0, 1]
        ]);
        result = math.multiply(result, transCenterT);
        let mStr = math.flatten(result)._data.join(',');
        mSlide.style.transform = `matrix3d(${mStr})`
    }

另外 CSS transform matrix3d 的值為列向量計算矩陣的轉置,上面全部使用轉置矩陣來計算。

   matrix3d( 
       a1, b1, c1, d1, 
       a2, b2, c2, d2, 
       a3, b3, c3, d3, 
       a4, b4, c4, d4)

還需要引入math.js文件。

DEMO 地址

參考文獻:

  1. 3D游戲與計算機圖形學中的數學方法-視截體
  2. 透視投影矩陣推導
  3. 三維旋轉矩陣
  4. 旋轉矩陣


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM