CSS matrix(a,b,c,d,e,f)
이번에는 CSS transform의 압축 파일 같은 녀석을 봅니다.
matrix(a, b, c, d, e, f)
처음 보면 여섯 숫자가 한 줄로 서 있어서 정이 안 갑니다. 그런데 이 숫자들은 아무렇게나 나온 값이 아닙니다. 2D affine transform을 표현하는 3x3 행렬을 CSS가 짧게 적은 것입니다.
겉은 퉁명스럽지만, 속은 꽤 체계적입니다.
여섯 숫자는 축과 원점이다
CSS matrix는 이렇게 읽을 수 있습니다.
a, b = 변환된 x축
c, d = 변환된 y축
e, f = 이동한 원점
행렬로 쓰면 이렇습니다.
| a c e |
| b d f |
| 0 0 1 |
점 (x, y)는 이렇게 변환됩니다.
x' = a*x + c*y + e
y' = b*x + d*y + f
여기서 e, f는 translate처럼 보입니다. 맞습니다. 원점이 어디로 이동했는지입니다.
a,b,c,d는 조금 더 재미있습니다. local x축과 y축이 화면에서 어디를 향하고 얼마나 길어졌는지를 담습니다. 그래서 rotation, scale, skew가 섞여도 이 네 숫자 안에 다 들어갑니다.
브라우저에서 읽기
computed style을 읽으면 브라우저가 계산한 최종 transform을 matrix 문자열로 돌려줍니다.
const value = getComputedStyle(element).transform;
그리고 DOMMatrixReadOnly를 쓰면 문자열 파싱, 곱셈, 역행렬 같은 작업을 직접 만들지 않아도 됩니다.
const matrix = new DOMMatrixReadOnly(value);
직접 구현하는 것도 공부에는 좋지만, 실제 제품에서는 표준 API를 잘 쓰는 편이 안정적입니다. 교수님도 가끔은 남이 해둔 일을 감사히 씁니다.
편집기에서 왜 중요할까
선택 오버레이가 content와 같은 matrix를 쓰면 화면 위치가 정확히 맞습니다. 외부 HTML을 에디터로 가져올 때나 computed transform을 디버깅할 때도 matrix를 읽을 줄 알아야 합니다.
다만 숫자 오차는 피할 수 없습니다. UI에 표시할 때는 적당히 반올림해야 합니다.
1.00000000002 -> 1
사용자에게 이런 숫자를 보여주면 수학이 아니라 공포를 가르치게 됩니다.
데모에서 볼 것
데모에서는 a,b,c,d,e,f 값을 바꾸며 basis vector와 원점이 어떻게 이동하는지 확인합니다.
오늘의 핵심은 matrix()를 외계어처럼 보지 않는 것입니다. a,b,c,d는 축, e,f는 원점 이동입니다. 이것만 잡아도 matrix가 꽤 말이 통하기 시작합니다.