LoginSignup
3
3

More than 3 years have passed since last update.

CSS transformは順番にご注意を

Posted at

基本

CSSでは、transform属性に複数の変換関数をつなげることができる。その際、関数は左から右に順番に適用される。transformは2次元、もしくは3次元のアフィン変換である。つまりどういうことかというと、こういうことである。

たとえば以下のようなCSSがあると仮定しよう。

transform.css
.transform {
  transform: rotate(90deg) scale(2);
}

この時、座標(x,y)について、以下のような計算を行う。

V = \begin{pmatrix}
2 & 0 & 0 \\
0 & 2 & 0 \\
0 & 0 & 1
\end{pmatrix} \begin{pmatrix}
\cos(90°) & -\sin(90°) & 0 \\
\sin(90°) & \cos(90°) & 0 \\
0 & 0 & 1
\end{pmatrix} \begin{pmatrix}
x \\
y \\
1
\end{pmatrix}

これにより求まった(x,y)がその地点が変換されて置かれる座標である。

なお、べた書きで行列を記述することも可能であるが、何が起きるか直感でわからない(=メンテナンスできない)からやめたほうがよい。

本題

transformは複数の変換関数をつなげることができるのだが、線形代数をやっている人にはわかると思うが、基本的に交換法則が成立しないという点に留意する必要がある。
交換法則が成り立つためには、ややこしい条件1が必要だが、2D transformに関して言えば、rotateとscaleの間、およびtranslate相互間については交換法則が成立する。
つまり、たとえば以下のようなCSSがあったとする。

sample.css
.test {
  transform: translate(20px,30px) rotate(45deg) scale(1.5) rotate(-15deg) scale(3) translate(10px,5px) translate(-20px,0) scale(2);
}

このようなCSSがある場合、こんな感じに交換できる。

sample2.css
.test {
  transform: translate(20px,30px) rotate(45deg) rotate(-15deg) scale(1.5) scale(3) translate(10px,5px) translate(-20px,0) scale(2);
}

簡単な行列計算で、rotate同士は角度の合算ができ、scaleは倍率が乗算ができる。また、translateは各座標値の合算ができるので、結局こうなる。

sample3.css
.test {
  transform: translate(20px,30px) rotate(30deg) scale(4.5) translate(-10px,5px) scale(2);
}

これ以上の簡略化はできないという点に注意せよ(translateとscale、translateとrotateの間には交換法則が成立しないため)。


  1. つまり、変換行列が$A$と$B$であるとする。その時にこの2つの行列が可換であるための必要十分条件はこの2つに、$P^{-1}AP$と$P^{-1}BP$がどちらも対角行列になる共通なある正則行列(逆行列が存在する行列)$P$が存在することである。 

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3