連載
» 2012年04月18日 00時00分 公開

Webグラフィックをハックする(1):5分でわかるCSSグラフィック (4/5)

[伊藤千光,WebOS Goodies]

2次元の変形

 従来のCSSでもpositionとleft, topなどの属性を組み合わせて要素の位置の変更(平行移動)は可能でした。しかし、animation属性などを活用したWebページを作っていると、回転や拡大縮小といった、よりインパクトのある変形が欲しくなってきます。そうした要求に応える手段がtransform属性です。

transformの書式 transformの書式

 transform属性による変形は該当する要素の表示のみに適用され、ページ全体のレイアウトフローには影響しません。このあたりはposition:relativeによる平行移動と同じです(ただし、transformによる変形はposition属性の値に関係なく適用されます)。

 transform-functionには実行する変形(座標変換)を定義する関数を記述します。原稿執筆時点では、以下の関数が定義されています。

  • translate(x, y) …… 平行移動
  • translateX(x) …… 横方向の平行移動
  • translateY(x) …… 縦方向の平行移動
  • scale(sx, sy) …… 縦横をそれぞれsx, sy倍に拡大縮小
  • scaleX(sx) …… 横方向の拡大縮小
  • scaleX(sy) …… 縦方向の拡大縮小
  • rotate(angle) …… 回転
  • skewX(angle) …… Y軸をangleだけ傾ける
  • skewY(angle) …… X軸をangleだけ傾ける
  • matrix(a, b, c, d, e, f) …… 行列による座標変換

 実際にこれらの変換を使った例をいくつか見ていきましょう。transform属性の動作はアニメーションさせた方が分かりやすいので、サンプルはすべてanimation属性と組み合わせてあり、コードはそのキーフレーム定義となっています。

 translate、translateX、translateYは要素を平行移動します。これはposition:relativeによる平行移動とほぼ同じ結果になります。値はCSSの長さの単位(px、pt等)で与えます。

 rotateは要素を回転させます。値は時計回りの角度(deg、rad、grad、turnのいずれか)です。

 scale、scaleX、scaleYは要素を拡大縮小します。値は単位なしの数値です。width、height属性と異なるのは、要素内の表示内容も同じ比率で拡大・縮小されることです。ここでもtransform属性はレイアウトフローに影響しないという点で一貫していますね。

 skewX、skewYはそれぞれY軸、X軸を傾ける「せん断変形」を行います。耳慣れない言葉かもしれませんが、要は全体を傾けるということです。値は回転と同様に角度の単位で指定します。

 平行移動以外の変換(回転、拡大縮小、せん断変形)には、変換の原点というものがあります。原点は変換後も移動せず、そこを中心として回転や拡大縮小が行われます。デフォルトでは要素の中心座標になりますが、transform-origin属性で変更できます。

transform-origin transform-origin 実際のサンプルを見る

 transform-originのパラメータは、長さの単位でx、y座標を数値指定するか、もしくはleft、topなどのキーワードを指定します。

 複数の変換の組み合わせ

 transform属性では、空白区切りで複数のtransform-functionを指定することで、複数の変換を同時に適用できます(カンマ区切りではないことに注意してください)。例えば移動しながら要素を回転させるようなアニメーションが簡単に実現できます。

複数の変換の組み合わせ 複数の変換の組み合わせ 実際のサンプルを見る

 複数の変換を組み合わせる場合、変換は最後のものから順に適用されます。従って、変換の記述順序によって結果が大きく異なる場合があります。

 例えばtranslate rotateの順で書いた場合は回転が適用された後に移動されるため、結果的に移動先で自転する動きになります。それに対して、rotate translateの順で書いた場合は、平行移動の後に原点中心の回転が適用されるので、原点を中心に要素が公転する動きになります。

複数の変換の組み合わせ 複数の変換の組み合わせ 実際のサンプルを見る

 一般的には、translate rotate skew scaleの順で書くと、感覚的な予想と最もマッチするはずです。しかし、常にこれが正しいわけではありませんし、変換の順序を工夫することで複雑な動きを簡潔に表現できることもあります。実際にいろいろな順序を試して結果の違いを把握しておけば、transform属性をより効果的に活用できるでしょう。

 また、複数の変換を組み合わせるもう1つのパターンとして、DOM階層の利用があります。入れ子になった要素の親と子どもの両方に変換を適用した場合、子どもには自身に設定された変換と親への変換の両方が適用されます。

 以下のサンプルは、上記の性質を利用して階層的な動きを表現した例です。transformの設定は単純な回転と平行移動ですが、それを入れ子になった4階層のdiv要素すべてに適用することで、紐が左右に揺れているような表現になっています(アニメーションカーブを調整していないので、かなり不自然ではありますが……)。

DOMの階層とtransformの関係 DOMの階層とtransformの関係 実際のサンプルを見る

 transform属性で行える個々の変換は非常に単純なものばかりですが、複数をうまく組み合わせることで多彩な動きを表現できます。いろいろな組み合わせを試してみてください。

 3次元の変形

 transform属性の拡張として、3次元の変形を行う機能も定義されています。長らくWebKitのみの機能でしたが、Firefox 10が正式にサポートし、IEも次期バージョンのIE 10で実装予定など、利用環境が急速に整いつつあります。

 3次元の変形は、transform-functionに以下の関数を追加することで実現されています。

  • translate3d(x, y, z) …… 平行移動
  • translateZ(z) …… 奥行き方向の平行移動
  • scale3d(sx, sy, sz) …… 縦横および奥行きをそれぞれsx、 sy、 sz倍に拡大縮小
  • scaleZ(sz) …… 奥行き方向の拡大縮小
  • rotate3d(x, y, z, angle) …… (x, y, z)で表されるベクトルを回転軸とする回転
  • rotateX(angle) …… X軸を回転軸とする回転
  • rotateY(angle) …… Y軸を回転軸とする回転
  • rotateZ(angle) …… Z軸を回転軸とする回転
  • perspective(length) …… パースの深さを指定する(後述のperspective属性の説明を参照)
  • matrix(16個の数値) …… 4×4行列による座標変換を適用する

 上記の関数群が追加されることを除けば、transform属性の書式は2次元の変形と同じです。したがって、画像を傾けて回転させるアニメーションは以下のように記述できます。

平行投影による3次元変換 平行投影による3次元変換 実際のサンプルを見る

 上の例はまだパース(遠くの物を小さく、手前を大きく描画する効果、いわゆる遠近法)を掛けていないので、単に縦につぶしただけのようにも見えます。パースを掛けるにはtransform属性を適用した要素の親要素にperspective属性を指定します。値は視点から画面までの距離ですが、だいたい1000px〜100px程度で適当な値を指定すればよいでしょう。値が小さいほど遠近が強調されます。

パースを掛けた3次元変換 パースを掛けた3次元変換 実際のサンプルを見る

 前述の通り、perspective属性はtransform属性を指定した要素ではなく、その親要素に指定しないと効果がありません。1つの要素だけでパースの指定も行いたい場合は、transform-functionのperspectiveを使用してください。こちらはその要素自身に適用されます。

 パースに関連するもう1つの属性としてperspective-originがあります。遠近法でいう消失点が指定します。言葉で説明するより、下の画像を見ていただく方が早いでしょう。デフォルトは左上の画像のように遠くのものが中心に収束していきますが、perspective-originを使うと、その収束する座標を自由に指定できます。

perspective-originの効果 perspective-originの効果 実際のサンプルを見る

 回転などによって要素が裏返ったときの表示を制御するbackface-visibilityという属性もあります。デフォルトはvisibleで、裏返ったときも表示されますが、hiddenを指定すると裏返った状態では非表示となります。下の静止画像ではよく分かりませんが、サンプルを見ていただければ効果が分かるでしょう。

backface-visibilityの効果 backface-visibilityの効果 実際のサンプルを見る

 ネストしたDOM要素に3次元変換を適用する際の挙動を制御するのが、transform-style属性です。デフォルトのflatが指定された状態だと、子要素は変換を適用した後にいったん親要素上にレンダリングされ、その結果の2次元画像に対して親要素の変換が適用されます。したがって、子要素のZ座標を変化させても画面上では親要素と同じ平面上に表示されます(下図左)。

 それに対して、transform-styleをpreserve-3dにすると、子要素が独立したオブジェクトとして描画されます。したがって、Z座標を変化させると、親要素の上(または下)に浮いたような形で表示されます(下図右)。

transform-styleの効果 transform-styleの効果 実際のサンプルを見る

 3次元の変形は、立体的な表現をWebページに持ち込むための、非常に強力な手段です。特にHTMLのすべての表示要素(inputタグ等も含む)を変換対象にできることは、FlashやCanvas、WebGLなどとまったく異なる特徴です。transform属性が普及すれば、思いもつかない新しいUIが生まれてくるかもしれません。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。