背景
2022年ごろから、独立transformプロパティとしてtranslate rotate scaleが各ブラウザに実装されました。
これにより、transformの上書きや処理順などを気にせずに座標変換をすることができるようになり、手軽に使用しやすくなりました。
transform: rotate()とrotateは、一般に同じ動作をすると思われており、実際にほとんどのケースでそれは間違っていないのですが、そうではない場合もあります。
概要
transform:rotate()とrotateはだいたい同じ動作をするが、offsetが絡むと違う動作をする。
実際の動作
以下のCodePenは、円形のモーションパスを移動させながらtransform:rotate()とrotateをそれぞれ360degまでアニメーションさせているものです。回転アニメーション以外のプロパティは全く同じです。
See the Pen transform:rotate() vs rotate by lhankor_mhy (@lhankor_mhy) on CodePen.
初見ではなぜこうなったかよくわかりませんでした。
なので、モーションパスを止めてみるとこうなりました。
See the Pen transform:rotate() vs rotate by lhankor_mhy (@lhankor_mhy) on CodePen.
ご覧の通り、回転の中心点が異なります。
解説
簡単な解説
rotateはtransform-originがoffsetによる変形の前の位置になります。言い換えると、offset-path: noneの時のtransform-originの場所を変形の原点とする、ということです。
逆にtransform: rotate()は、offsetによる変形後の、見たままのtransform-originです。
図示
See the Pen rotate and offset by lhankor_mhy (@lhankor_mhy) on CodePen.
仕様
仕様書によると、このようになっています。
The transformation matrix is computed from the transform, transform-origin, translate, rotate, scale, and offset properties as follows:
- Start with the identity matrix.
- Translate by the computed X, Y, and Z values of transform-origin.
- Translate by the computed X, Y, and Z values of translate.
- Rotate by the computed about the specified axis of rotate.
- Scale by the computed X, Y, and Z values of scale.
- Translate and rotate by the transform specified by offset.
- Multiply by each of the transform functions in transform from left to right.
- Translate by the negated computed X, Y and Z values of transform-origin.
変形行列の合成について正直しっかり理解できていないのですが、translate→rotate→scale→offset→transformの順番に処理がされるようです。
rotateが処理された後にoffsetが処理され、さらにその後にtransformが処理されていることが、この動作の違いを生んでいるのだろうと思います。
ですので、rotateだけではなくて、translateやscaleもこの影響を受けています。