〽️反対の軸が傾斜。 〽️傾斜の方向。 〽️大きさが変わらないので大きくなる。 〽️90°以上を考える。 〽️XYskewのとき。 〽️座標変換につながる思考。
⬆︎CSSアニメーションについてのまとめページはこちら。
こんにちは、「ふ」です。
CSSアニメーション、transform編。前回transform:skewについて取り上げたのですが、なんとも予測不能な動きをしていました。
これ⬆︎は要素にskewX(1〜360°)を指定した場合の様子です。
transform:skewは他のtransform関数と違い、いまいち「直感的ではない」動きをします。
・どういう仕組みで傾斜しているの?
・X/Yで傾斜方向が違う?
・なぜ大きくなるのか?
・180°ごとにループする理由は?
skewを操作していると、さまざまな疑問にぶち当たります💧
そこで今回はtransform:skewの根本的な仕組みについて説明していきたいと思います。
仕組みを知ることである程度の結果を予想することができ、予想外の事態を回避しやすくなるでしょう。
幅100px、高さ100pxの要素があったとします。
これを座標空間で見たとき。
web要素における座標はX軸が右から左、Y軸が上から下へと伸びています。
原点を要素の左上とするとこの要素の成分は、
X成分は「+方向に100px」
Y成分は「+方向に100px」
と考えることができます。
ここにskewXを指定すると、内部的にどのように処理されているのでしょうか。
html要素のtransform-origin(変形の基準)は初期値が「center」となっています。記事内では要素のXY成分と座標の原点を一致した方がプレビューしやすいため、左上に指定しておきます。
#element { transform-origin:「「4left top」」; transform:「「1skewX(20deg)」」; }
見た目の結果がこちら。
ここにさっきのXY成分を割り当ててみます。
XY成分の矢印を配置すると、このように。
おや? 「skewX」としたのに、角度がついているのはY成分のほうです。
そうです、transform:skewXとすると、変形するのはX軸ではなく垂直に交わっているY軸に角度がつけられているんです。
transform:skewでは、指定した方向と交差している成分が傾斜している。
transform:skewを指定すると、skewXの場合は反時計回りに、skewYの場合は時計回りに要素が傾斜します。
なぜそのような現象になるのか?それは先程のX成分、Y成分の動きで説明がつきます。
transform:skewX「「1(20deg)」」;
skewXに正の値20°を指定しました。このとき内部的には直交するY成分が変形します。「正の値」が与えられているので、Y成分もx軸の「+」の方向(左から右)に向かって傾斜します。
この動きに要素を当てはめると、半時計周りに歪んでいく状態に。
指定角度をマイナスの値にしてみます。
transform:skewX「「1(-20deg)」」;
角度にマイナスの値を指定したので、今度はY成分がx軸に対して逆方向に傾斜します。したがって要素も時計回りにskewします。
今度はskewYで試します。 web上の座標定義では、y軸は下が正の方向でした。
transform:skewY(20deg);
skewYでは、X成分が傾斜します。角度を「プラス20°」としているので、その方向はy軸の正の方向、下向きです。
X成分の傾斜にともない、要素は時計回りに歪みました。角度にマイナスの値に指定すると、逆方向に歪みます。
成分の歪み方向は軸のプラス方向に向いているため、skewX/Yで要素の傾斜方向が逆になるのです。
直交成分の傾斜の方向はskewの指定方向に準ずる。これが時計/半時計周りの原因。
次なる疑問。
skewにおいて、角度が90°に近づくにつれてなんだか要素全体がでっかくなってしまします。
「傾斜」させたかっただけなのに、なぜこのようなことが起こるのでしょうか?
先程の100px*100pxの要素で考えてみましょう。
skewする前のX成分に注目。
X成分自身の大きさは、「+方向に100px」です。
Y方向に45°傾斜させてみます。
#element { tranform:skewY(45deg); }
先の章で検証したように、skewYのときには指定方向の交差成分、つまりX成分が傾斜します。
そしてこのとき、⬆︎のようにはなりません。
skewの性質を知る上でのカギがここにあります。
X成分は、もともとのX値(+方向に100px)を保持したまま傾斜していきます。
となると、45°傾斜したときには成分自体の長さは拡大される、ということに成増。
要素を当てはめてみました。
X成分の長さが伸びていく。結果それに伴うことで要素も大きくなっていくのです。
これが「傾斜がつくほど要素が大きくなる」理由です。
傾斜する成分は、自身のX値またはY値を保持したまま変形していく。
ここまでは傾斜が90°より小さい場合の動きを見てきました。
skewの値を90°以上にした場合、どのような現象となるのか、見ていきます。
#sample { transform:skewX(45deg); }
現在要素はX方向に45°傾斜しています。
傾斜角度を大きくしてみましょう。
transform:skewX(90deg);
「skewX」なのでY成分がどんどん傾斜していきます。
そして90°に達したとき。要素は「限りなく細長い平行4辺形」となるため、存在はしているのですが見えなくなってしまいます。
そして角度が90°を超えたとき、成分を表す矢印はどのような状態になるのでしょうか?
transform:skewX(135deg);
現在skew135°。
XY成分の状態、フツーに考えるとこう⬆︎なるのかと。
これではルール違反になってしまうのです。
この状態のY成分のY値は、「マイナス方向に100px」となってしまっています。
前のセクションの「傾斜するY成分は、自身のY値を保持したまま変形していく」という決まりにのっとれば、「プラス方向に100pxを保持したままで傾斜をとる」必要があります。
「プラス方向に100pxで傾斜135°」にするとしたら。。
Y成分の位置はこの⬆︎ように。
傾斜角が90°を超えた場合、「プラス方向に100px」を維持すべく、要素は対角上に回り込んでしまうのです。
現在のXY成分に要素を当てはめると、反対側に傾斜していることがわかります。
90°前後における、Y成分の動きです。
0~90°までは「傾斜の量が増えていく」状態でしたが、90°を過ぎてからは「傾斜の量が減っていく」ように進んでいきます。
skew90°は、「正の方向に傾斜しきった状態」であり、また「負の方向に傾斜しきった状態」でもあるのです。
これがskewXを0°から180°まで変化させた様子です。90°をすぎると反対方向から傾斜の量が減っていき、180°で傾斜がまったくない状態 = 最初の状態に戻ります。
さらに、180°〜270°の範囲も考えてみましょう。
skewのルールを考えずに角度を付けた場合、Y成分は左上の範囲で変化するのですが、
やはり「プラス方向に100px」を維持すべく、Y成分は対角に回り込みます。
そして270°〜360°に関してはフツーに「プラス100px」を維持できるので、そのままの領域で傾斜することができます。
これって、0〜180°の時と同じ傾斜範囲ですよね?
そうです。0〜180°の変化と180〜360の変化は同じ状態に成増。
つまり、transform:skewは180°ごとに変化がループするということです。
■ transform:skewは、90°〜270°の間は傾斜成分が対角に回り込み、半周ごとに現象がループします。
ここからはX、Y両方の成分をskewさせた場合の動きを見てみましょう。
ここでも不思議な結果が出ることがあります。
傾斜したX成分の角度をxdeg、Y成分のydeg、2つの成分がなす角度をθとします。
ここまでの結果から、X、Y成分の行動範囲は座標上で⬆︎のように表すことができます。
2つの成分がなす角度θは、0〜270°の範囲で変化するということになるのですが、θの状態により、要素の状態が大別されます。1つずつみていきましょう。
以下、θの状態別に挙動を示していきます。
ただしxdeg、ydegのいずれかが90°/270°であれば、 θの状態にかかわらず無限に膨張されてしまい、表示されません。「それ以外の状態」であることを前提に話を進めていきます。
transform:skew(30deg,60deg);
xdegとydegの合計が90°や270°となるとき、2つの成分は重なってしまいます。θ = 0の状態です。
要素が完全につぶれてしまうため、何も表示されません。
transform:skew(-30deg,-15deg);
2つの成分の角度が0°と180°の間であれば、自然なskewの結果と成増。
結果は想像どおりですね。
transform:skew(45deg,-45deg);
先ほどの0°と180°の間において、θが90°になる時があります。
この場合2つの成分は直交しているので、要素の傾斜は起こりません。
ただし各成分の傾斜の深さによって、要素が膨張する度合いも変わってきます。
transform:skew(150deg,-60deg);
X、Y成分が1直線上になってしまった状態です。
お察しのとおり、要素が完全につぶれてしまって表示されません。
transform:skew(-60deg,-60deg);
2つの成分のなす角度が180°を超えてしまった場合、どうなってしまうのか。
本来要素はX、Y成分の成すL字型に囲まれるように配置されるのですが、θが180°以上の場合には、L字型の関係が反転してしまっています。
結果。X/Y成分の反転に伴い、要素自体も反転します。
あくまで2つの成分の作る「内角側」に要素は描画されるのですね。
X/Y成分の反転は、両者の共通の行動範囲である⬆︎の部分でも起こり得ます。
xdegとydegの合計が90°を超える場合です。
transform:skew(60deg,60deg);
X/Y成分の位置関係が逆転してしまっています。
成分の逆転により、要素も反転しました。
transform:skewの内容をここでまとめておきます。
この5つで、skew全ての現象に説明がつきます。
① 指定した方向と交差している成分が傾斜する。
② 成分の傾斜方向は指定方向の軸の向きとおなじ。
③ 傾斜成分は、自身のX値またはY値を保持したままというルールを持っている。
④ 90°〜270°の間は傾斜成分が対角に回り込む。
⑤ XY両方を傾斜したときは、2つの成分の角度によって状態が変化する。
最後までお読みくださり、ありがとうございました。
長々と説明を続けてきましたが、今回skewの説明に使ったお話は、「座標変換」という考え方です。
CSSを学習中の方なら、transform:matrixというものを聞いたことがあるでしょうか?
ここでの内容は、matrix(座標変換)に通ずるものがあります。興味をお持ちでしたら、是非チャレンジしてみてください。
ではまた〜 ♩
transform:matrixを理解する。
2021.06.14
行列計算は必要なし。
swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。