イナヅマTVログ

CSS3 transform matrix 3D

ActionScript脳で覚えるCSS3 transform matrix 2D 少しだけ3D – 道半ば

| 1件のコメント

CSS3には拡大、縮小、移動、傾斜、回転を行えるtransformプロパティがあります。
このtransformは2D, 3Dどちらにも対応しています。

ASのtransform.matrix(Matrix)も得意では無かったのですが、復習がてらのメモです。

W3C: CSS Transforms

transform(matrix)で最適化

DOMElementのアニメーションでパフォーマンスを良くするためにはtransformを使った方が良いと、あるセミナーでGoogleの中の人とMozillaの中の人が言ってたので間違いないでしょう。
て言うか信じてます、試しては無いです。伝聞で申し訳ないです。

でもカクカク動いてたiPhone上でのアニメーションをtransformに変えたらかなりスムーズに動くようになったので効果はあると思っています。

  • 追記 –
    スマホのアニメーションが改善されたって話ですが、
    translateZ(0)を指定しGPUレンダリングが有効になるようにしていました。
    単にmatrixを使うだけ、2Dの場合など、では効果は無かったかもしれません。
  • 追記終 –

transform 2D

2Dから。

とはいえ CSS transform: matrix は2D, 3Dどちらにも使います。
Matrix, Matrix3Dと明確に分かれているActionScriptとは違います。

ScriptとCSSでは言語の性質が違うからでしょうか。

それぞれの値設定に translate, translateX, translateY, rotate, skewX, skewYが使えます。
MDNによればskewは廃止され使えなくなったそうです。
なんでだろ?
MDN: transform

またmatrixを使い同様のことが行えます。

デモを作りました。

css3 transform matrix

transform-origin

注意した方が良いなと思ったのは、defaultではDOMElementの中心を起点に変形が行われることです。
どこを起点にするのかは transform-origin プロパティで設定します。

transform-origin: 50% 50%;

デフォルトは50% 50%( center center )になっています。
DOMElementの中心が起点です。

Flashは基準点を左上(TOP LEFT)にすることが多いので微妙に結果が違い少し焦りました。

matrix

matrixはActionScript Matrixとほぼ同じです。
ActionScript: Matrix

ActionScript

Matrix(a:Number = 1, b:Number = 0, c:Number = 0, d:Number = 1, tx:Number = 0, ty:Number = 0)

CSS
via:MDN transform

transform:  matrix(a, c, b, d, tx, ty)

名前の付け方が違うので戸惑うのですが、中身は同じです。

   ┌     ┐ 
   │ a b │
   │ c d │
   └     ┘

a: 水平方向の縮尺(0~1)
c: 垂直方向の傾斜率(rad)
b: 水平方向の傾斜率(rad)
d: 垂直方向の縮尺(0~1)
tx: 水平方向の移動距離(px)
ty: 垂直方向の移動距離(px)

transform:  matrix(1, 0, 0, 1, 0, 0)

が 拡大・縮小・変形・回転・移動 無しになります。

tx, ty と translate, translateX, translateY

CSSのtransformでの移動は移動量(px)を設定値に渡します。
例えば translateX( 20px ) では現在座標から20px右に移動です。

translate( tx, [ty] );
translateの時tyは省略可能で、省略されるとtxの値が使われます。

ASでは現在座標から右に20px移動だと現在のtransform.matrix.txを加算しないといけません。

var mtx:Matrix = mc.transform.matrix
mtx.tx += 20;
mc.transform.matrix = mtx;

デモ説明

ソースは見れるのでそちらを参照してください。
CSSはCompassで作成ました

@include transform( translate( 0, -20px ) );

ベンダープレフィックス付きのCSSを吐き出してくれます。

-webkit-transform: translate(0, -20px);
-moz-transform: translate(0, -20px);
-o-transform: translate(0, -20px);
-ms-transform: translate(0, -20px);
transform: translate(0, -20px);

skew

skewが廃止され代用はmatrixを使用します。

transform:  matrix(1, tan(rad), 0, 1, 0, 0)
transform:  matrix(1, 0, tan(rad), 1, 0, 0)

関数を持たないCSSで三角関数 tan を使い設定しないといけないのは奇妙に思えます。
skewX, skewYがあるので困ることは無いでしょうけど。

skewX, skewYはrad, degの単位付き数値を設定します。

どうしてもmatrixで設定したい時はJavaScriptを使うしか無いようです。

(function ( window ){
    "use strict";
 
    var document = window.document,
        _PI = Math.PI,
        _RAD = _PI / 180,
        _DEG = 180 / _PI
    ;
 
    function isNumeric ( obj ) {
        return !isNaN( parseFloat( obj ) ) && isFinite( obj );
    }
 
    function radToDeg ( rad ){
        return _DEG * rad;
    }
 
    function degToRad ( deg ) {
        return _RAD * deg;
    }
 
    /**
     *
     * @param {number} [a=1] horizontal (x) scale
     * @param {number} [c=0] vertical (y) skew
     * @param {number} [b=0] horizontal (x) skew
     * @param {number} [d=1] vertical (y) scale
     * @param {number} [tx=0] horizontal (x) move
     * @param {number} [ty=0] vertical (y) move
     * @returns {string} css style transform:matrix を返します
     */
    function createMatrix ( a, c, b, d, tx, ty ) {
        if ( !isNumeric( a ) ) {
            a = 1;
        }
        if ( !isNumeric( c ) ) {
            c = 0;
        }
        if ( !isNumeric( b ) ) {
            b = 0;
        }
        if ( !isNumeric( d ) ) {
            d = 1;
        }
 
        if ( !isNumeric( tx ) ) {
            tx = 0;
        }if ( !isNumeric( ty ) ) {
            ty = 0;
        }
 
        var prefix = [ "-webkit-", "-moz-", "-o-", "-ms-", "" ],
            i,
            limit = prefix.length,
            css = ""
        ;
 
        for ( i = 0; i < limit; i++ ) {
            css += prefix[ i ] + "transform:matrix(" + [ a, c, b, d, tx, ty ].join( "," ) + ");";
        }
 
        return css;
    }
 
    var m12 = document.getElementById( "m12" );
    m12.style.cssText = createMatrix( null, null, Math.tan( degToRad( 29 ) ) );
 
}( window ));

こんな関数を作りました。

matrix 3D

とても分かりやすかったサイトがありました。
Intro to CSS 3D transforms

そのまんまじゃん、なデモを練習がてら作成しました。

別の機会に理解できたことをまとめてみたいと思います。
いつかきっと…
CSS3 transform matrix 3D

1件のコメント

  1. ピンバック: CSS3 animation + transition, 「HTML5+α初心者勉強会 @福岡 第1回」資料を公開しました « イナヅマTVログ

コメントを残す