昨日のこれ ↓ を作る際に使ったtransform属性のmatrixパラメータについて、サンプルのHTML+CSSを付けて補足します。サンプルの動作確認はChrome43、Firefox39、IE10でしました。
元テーブル
下のテーブルを元にします。左上隅のセル内に、背景色付きのDIV要素をぴったりはめ込みました。これを段階的にtransform:matrix()で変形させ、セル内斜線にする過程を示します。テーブルの他のセルはmatrixの各パラメータの値。a~d, txおよびtyはMozilla Developer Network - transformの説明にある変数名と同じ。間違いやすいのは、パラメータの順番が(a, c, b, d, tx, ty)でbとcが逆な点です。
下のようにaとdが1、他がゼロの場合、単位行列を掛けるだけの1次変換を意味するのでDIV要素は変化しません(恒等変換)。
Image
右下がり
次に、パラメータcにtanθを入れると、横軸からみて角度θ分だけ縦に傾斜します(シアー、スキュー、またはせん断とも言う)。今回、対角線と平行に傾斜させるのでθが対角線と横軸のなす角に等しくなり、tanθイコールDIV要素の「縦の長さ÷横幅」になります。
間違いやすいのは正負の向きで、CSS3では縦軸が「下へ行くほど大」で普通の数学等の座標と逆。だから右下がりに傾斜させる時、パラメータcの符号は正になります。
| a=1 | b=0 | tx=0
|
| c=height/width | d=1 | ty=0
|
Imagetransform: matrix(1, 0.625, 0, 1, 0, 0);
/*
0.625 = height(50) / width(80)
*/
上は、とりあえず変形の原点を考えずテストしたようなもの。CSS3の場合、変形する要素の中心が原点となるようで、傾斜したDIV要素がセルの上下に均等にはみ出しています。そこで次に、DIV要素を「縦に延びた長さの半分」だけ下にずらす。単純な平行移動です。縦に延びた長さは、元の縦の長さと同じ。
matrixのパラメータtx, tyが平行移動の量で、先ほど書いた「縦軸の向き」のとおり下へ移動する時パラメータtyが正になります。下がその結果。
| a=1 | b=0 | tx=0
|
| c=height/width | d=1 | ty=25
|
Imagetransform: matrix(1, 0.625, 0, 1, 0, 25);
/*
0.625 = height(50) / width(80)
25 = height(50) / 2
*/
これでセル内の右下がり斜線の原型が完成。後は背景色を消し、上側だけにborderを設定するだけ。それは昨日すでに行っているので省略します。
右上がり
前項と違うのは傾斜の向きだけ。まずパラメータcを負にすると ↓ こんな感じ。
| a=1 | b=0 | tx=0
|
| c=-1*height/width | d=1 | ty=0
|
Imagetransform: matrix(1, -0.625, 0, 1, 0, 0);
/*
-0.625 = -1 * height(50) / width(80)
*/
前項と同様、要素の中央を原点として変形されたので、上下に均等にはみ出し。そこで同様にパラメータtyを入力して下方向に移動させ、斜線の原型ができます。
| a=1 | b=0 | tx=0
|
| c=-1*height/width | d=1 | ty=25
|
Imagetransform: matrix(1, -0.625, 0, 1, 0, 25);
/*
-0.625 = -1 * height(50) / width(80)
25 = height(50) / 2
*/
その他
昨日は使いませんでしたが、transform属性またはmatrixパラメータを少し別に変えても、同じ斜線ができます。例えば平行移動をせず、始めから変形の原点を要素の上端に設定して(transform-origin: 100%)行ったのが ↓ こちら。CSSのプロパティが一つ増える一方、算出に必要な値が一つ減ります。
| a=1 | b=0 | transform-origin
|
| c=-1*height/width | d=1 | 100%
|
Imagetransform: matrix(1, -0.625, 0, 1, 0, 0);
transform-origin: 100%;
/*
-0.625 = -1 * height(50) / width(80)
*/
また傾斜変形でなく「回転」「拡大」を合成して ↓DIV要素の上辺をセル対角線に一致させることも可能。合わせて変形の原点を左上隅に設定しています。
| a=1 | b=height/width | transform-origin
|
| c=-1*height/width | d=1 | 100% 0%
|
Imagetransform: matrix(1, -0.625, 0.625, 1, 0, 0);
transform-origin: 100% 0%;
/*
0.625 = height(50) / width(80)
*/
本来、回転と拡大の合成変換でmatrixに渡すパラメータは、拡大率をr、回転角をθとすれば(a, c, b, d)=(r⋅cosθ, r⋅sinθ, -r⋅sinθ, r⋅cosθ)ですが、拡大後のDIV要素の上辺が元の対角線になるので拡大率rはsqrt(x2+y2)/x(xはDIVの横サイズ、yは縦サイズ)、cosθはx/sqrt(x2+y2)、sinθはy/sqrt(x2+y2)なので、結局パラメータは上のように簡単になります。
ただFirefoxで上のように回転させて斜線にすると、傾斜変形の時より線が太くなった気がしました。実際作ってる図形が違うので、描画される線の幅が異なることは十分ありそうです。