【CSS3】 要素を変形させる transform をやってみた。

CSS3のHTML要素を自在に変形させられる機能 transform をやってみた。

transform と transform-origin

transformプロパティ は、変形の支点を指定する transform-originプロパティ とセットで使用する。

変形の支点を指定する transform-origin

最初に、transform-origin を指定する。
transform は、回転や歪みを指定するが、その支点をどこに置くかを指定するのが transform-origin だそうだ。

<style type="text/css">
  .transform{
       -moz-transform-origin:center center;
    -webkit-transform-origin:center center;
        -ms-transform-origin:center center;
         -o-transform-origin:center center;
            transform-origin:center center;
  }
</style>

指定値は background-position と同様の指定(横方向 縦方向 の順に、左上からのピクセル数指定、パーセント指定の他、横キーワード left, center, right、縦キーワード top, center, bottom)ができる。

この例で指定した center center は、縦も横も真ん中を支点にする指定。

transformプロパティと関数

実際の変形内容は transformプロパティに、関数を指定して指示する。

transform: 関数(引数) 関数(引数) 関数(引数) ...;

ここで、関数という概念が登場する。関数は変形の機能の定義で、関数名の後ろに括弧をつけ、詳細な指示を引数として指定して使う。

関数と関数の間に半角スペースを空けることで、一度に複数の関数を適用することができる。

現在あるモダンブラウザが実装できている関数は下記の通り。

rotate
回転
translate
移動
scale
拡大/縮小
skew
X軸、Y軸へのゆがみ

ちなみに、(すでに結構古い記事ではあるが)こちらの記事(gihyo.jp)によると、その他にも定義されているが未実装の機能があるらしい。

backface-visibility
要素の裏側の可視・不可視
perspective
奥行き
perspective-origin
奥行きの支点
transform-style
2D(flat)と3Dの指定

関数を適用してみた

とりあえず、すぐに利用できそうな、 rotate(), translate(), scale(), skew() の4つを試してみる。

赤く表示されている枠は、本来要素があるはずの領域で、この枠を基準に、どう変形したのかを確認できるようにしてみた。(キャプチャは Safari4.0.5 でレンダリングしたもの)

1つ1つ見ていってみる。

rotate() ~ 回転

rotate()してみた図(Safari 4.0.5)

rotate() は回転の効果を得る関数で、引数に回転の角度を取る。角度の単位は deg (degree)で指定する。例えば、右に45度回転させたいときは、45degとする。負の値も指定できる。

<style type="text/css">
  .transform_rotate{
       -moz-transform:rotate(45deg);
    -webkit-transform:rotate(45deg);
        -ms-transform:rotate(45deg);
         -o-transform:rotate(45deg);
            transform:rotate(45deg);
  }
</style>

translate() ~ 移動

translate()してみた図(Safari 4.0.5)

移動を実行する translate() は、右方向と下方向の2つの引数を取る。負の値も指定できる。

<style type="text/css">
  .transform_transrate{
       -moz-transform:translate(20px,10px);
    -webkit-transform:translate(20px,10px);
        -ms-transform:translate(20px,10px);
         -o-transform:translate(20px,10px);
            transform:translate(20px,10px);
  }
</style>

scale() ~ 拡大縮小

scale()してみた図(Safari 4.0.5)

要素を拡大縮小させる scale() は、横の拡大率と、縦の拡大率の2つの引数を取る。原寸を1として、少数を指定する。負の値も指定できる。古いIEの独自実装だったzoomプロパティと似ている。

<style type="text/css">
  .transform_scale{
       -moz-transform:scale(1.1,0.5);
    -webkit-transform:scale(1.1,0.5);
        -ms-transform:scale(1.1,0.5);
         -o-transform:scale(1.1,0.5);
            transform:scale(1.1,0.5);
  }
</style>

skew() ~ 歪み

skew() は、X軸方向、Y軸方向への歪みを指定する。単位は rotate() と同じく deg(角度)。負の値も指定できる。

skew()してみた図(Safari 4.0.5)

<style type="text/css">
  .transform_skew{
       -moz-transform:skew(10deg,30deg);
    -webkit-transform:skew(10deg,30deg);
        -ms-transform:skew(10deg,30deg);
         -o-transform:skew(10deg,30deg);
            transform:skew(10deg,30deg);
  }
</style>

全部指定してみる。

全部指定してみた図(Safari 4.0.5)

前述の通り、関数の間をスペースで区切って、一度に複数の関数を適用できる。

<style type="text/css">
  .transform_all{
       -moz-transform:rotate(45deg) scale(1.1,0.5) skew(10deg,30deg) translate(20px,10px);
    -webkit-transform:rotate(45deg) scale(1.1,0.5) skew(10deg,30deg) translate(20px,10px);
        -ms-transform:rotate(45deg) scale(1.1,0.5) skew(10deg,30deg) translate(20px,10px);
         -o-transform:rotate(45deg) scale(1.1,0.5) skew(10deg,30deg) translate(20px,10px);
            transform:rotate(45deg) scale(1.1,0.5) skew(10deg,30deg) translate(20px,10px);
  }
</style>

関数を適用する順序によって効果が変わる

transformの関数は、かける順番によって効果に影響するので注意が必要だ。

次の図は実際に順番を入れ替える実験を行った図。transform-origin:left top; に設定し、translate(100px,0px) scale(0.5,1)(パターン1) としたときと、順番を入れ替えてscale(0.5,1) translate(100px,0px)(パターン2) としたときの移動距離は異なることが確認できる。原寸の時(パターン1)の移動距離100pxが、半分の幅(パターン2)にしたので50px移動している。

transform の関数の順番を入れ替えるテストの図

matrix関数

変換行列をもとに変形を指定する関数 matrix() も使えるそうだ。これについてはよく理解できていないのだが、引数として6つの数字を与えて変形させるそうな。

あまり深く考えてはいないが、取り急ぎ適当なサンプルソースを作ったので、載せておく。

#transformer{
     -moz-transform:matrix(1,2,3,4,5,6);
  -webkit-transform:matrix(1,2,3,4,5,6);
      -ms-transform:matrix(1,2,3,4,5,6);
       -o-transform:matrix(1,2,3,4,5,6);
          transform:matrix(1,2,3,4,5,6);
}

この結果、下記のような効果が得られた。なぜこうなるのかは理解できていない。

matrix()のテストの図

後でもう一回考え直してみます。

変形をアニメーションする

少々蛇足だが、translation と組み合わせて、徐々に変形する簡単なアニメーションを実装してみる。

詳しくはサンプルソースのソースコードを読んでもらいたいのだが、このサンプルのポイントだけざっくり触れてみるので、ご参考までに。

まず、アニメーションするHTMLは下記。transformer というIDを振った。

<div id="transformer">
    transform, transition でアニメ<br />
    transform, transition でアニメ<br />
    transform, transition でアニメ<br />
    transform, transition でアニメ<br />
</div>

アニメーションする設定は、transition を設定している。transition については過去の記事 【CSS3】 transition を使ってアニメってみた。 を参照。Firefoxはまだtransitionが実装されていないようなので、アニメーションはしない。

あと、transform-origincenter center に設定した。

#transformer{
     -moz-transition:   -moz-transform 3s ease-in-out;
  -webkit-transition:-webkit-transform 3s ease-in-out;
      -ms-transition:    -ms-transform 3s ease-in-out;
       -o-transition:     -o-transform 3s ease-in-out;
          transition:        transform 3s ease-in-out;
     -moz-transform-origin:center center;
  -webkit-transform-origin:center center;
      -ms-transform-origin:center center;
       -o-transform-origin:center center;
          transform-origin:center center;
}

次に、JavaScriptからCSSのtransformプロパティをコントロールする部分。elm.style.transformだけではダメで、DOMからコントロールする場合にも、ベンダープレフィックスを付ける必要があるようだ。

<script type="text/javascript">
function transform_element( transform_to ){
  var elm = document.getElementById('transformer');
  elm.style.transform =
  elm.style.webkitTransform = //←Webkit用
  elm.style.MozTransform = //←Firefox用
  elm.style.OTransform = //←Opera用
    transform_to;
}
</script>

これで、transform_element( ${transformプロパティの値} )を実行すると、アニメーションしながら要素が変形するようになっているはず。

まとめ

transformプロパティひとつでたくさんの変形メソッドを指定するので、実際に使用するときには、値の管理に気を使うことになりそう、という予感。

あと、例のgihyo.jpの記事によれば、"3Dを基本に考えるべし" とあるが、この実験で扱ったのは全部2Dなので、3Dで扱うとどうなるのかは、また後の課題として残す。(ちょっと前に話題になった3Dでアニメーションするスーパーマリオなども参考に)

この実験で使用したブラウザは下記の通り。IE以外のメジャーなブラウザでは既に動くようになっている。

Internet Explorer 8 ×
Firefox 3.6.3
Safari 4.0.5
Google Chrome 5.0.375.86
Opera 10.60
iPhone 3GS (iOS4) Mobile Safari

今回の実験では触れなかったが、IE8にもtransform とは別に、変形を実現する方法があるそうだ。

参考にさせていただいたウェブページは下記。

関連記事もどうぞ。


プロフィール

ときにはデザイナ、ときにはディレクタ、ときにはプログラマ、ときには何でも屋と、ウェブの世界で未熟ながらもいろいろやっている、コヤナギトモヤです。

ツイッター上ではこのヒト。
@tomk79

RSSフィード

ページの先頭へ戻る