2025-06-19

CSS / JS 的圖形矩陣處理

眾所周知,CSS 的 transform 或是 SVG 的 transform 可以使用 translateX、rotateX、scale……等 transform functions。而裡面最為複雜的就是 matrix

參閱 MDN 的說明, matrix 有 6 個參數:matrix(a, b, c, d, tx, ty) ,以投影座標(因為我常用的 GIMP 、我當初學的都是使用投影坐標(projective coordinates),我這篇也都使用投影座標來講)來表示的話,就是:

( a c tx b d ty 0 0 1 )

如果今天我 CSS 是 translateX(100px),那相當於matrix(1, 0, 0, 1, 100, 0),即: ( 1 0 1 0 100 0 0 0 1 )

今天我遇到的問題是:我有一個 HTML element,他可能會做一些變換,例如旋轉,然後我有一個按鈕會讓它移動

最簡單的做法就是在 transform CSS 最後加上 translate,例如

element-selector{
	transform: translate(200px, 13px) rotate(90deg)   /* 在最後面加上: */ translateX(100px)
}

還有一種做法是將原先的 transform 改成 matrix,然後再進行移動,以上面為例translate(200px, 13px) rotate(90deg)的 matrix 為 matrix(0, 1, -1, 0, 200, 13),即: ( 0 -1 200 1 0 13 0 0 1 )

之後再移動 100px,得到的 matrix 就會是: ( 0 -1 200 1 0 113 0 0 1 )

JS 處理

今天我要使用 javascript 來更改 HTML element 的 transform,現在有DOMMatrixReadOnly來處理。

例如我現在有個 <div> 如下

<div id="transform-demo-div" style="transform: translate(200px, 13px) rotate(90deg)"></div>

要再加上 translateX(100px) 的動作,可以這樣:

const div = document.getElementById("transform-demo-div")
const transformStyle = div.style.transform
const matrix = new DOMMatrixReadOnly(transformStyle)

div.style.transform = matrix.translate(100, 0).toString() 

執行完這段 js 後,該 div 的 transform 樣式就會變成 transform: matrix(0, 1, -1, 0, 200, 113);

角度相關

這邊要提一下旋轉(rotate)和扭曲(skew)

根據文件,DOMMatrixReadOnly.prototype.rotate的參數有三個:rotate(rotX, rotY = undefined, rotZ = undefined)

經過測試,這個 rotX/Y/Z 的單位是角度,而不是弧度,換言之, new DOMMatrixReadOnly("rotate(20deg)")new DOMMatrixReadOnly().rotate(20)兩者是相同的。可以見下:

rotate(20deg)
new DOMMatrixReadOnly().rotate(20)

同理,扭曲也同樣以角度為單位,new DOMMatrixReadOnly("skewX(20deg)") 等同於 new DOMMatrixReadOnly().skewX(20)

skewX(20deg)
new DOMMatrixReadOnly().skewX(20)

參考資料

MDN 的相關條目
Techwisdom. (2020, November 2). Re: How to Get Value TranslateX by Javascript. Stack Overflow. https://stackoverflow.com/a/64654744

沒有留言:

張貼留言