perspectiveプロパティをつかって、パララックス効果などの奥行きのある表現をしてみる

この記事は、Tech KAYAC Advent Calendar 2016 の23日目の記事です。

はじめまして!今年春に入社した、HTMLファイ部の @beeeeinto です 👩

今回は、CSSプロパティの一つであるperspectiveについて説明していこうと思います。

もくじ

  • perspectiveプロパティとは
  • ブラウザ対応状況
  • perspectiveプロパティで出来ること
  • 気をつける点など
  • さいごに

perspectiveプロパティとは

perspectiveは、ユーザーの視点を指定するためのプロパティです。
z=0平面からどれだけ離れた視点から要素を見るかを指定します。

詳しくは、MDNやW3Cなどのドキュメントを参照するのをおすすめします。

perspectiveプロパティで出来ること

簡単にいうと、perspectiveを使うことで、平面的なWebサイトで「奥行き」を表現することができます。

今ではよく見るパララックススクロールも、このプロパティを使っていい感じにスタイリングすれば、JSを使用しなくても作ることが可能です。

ということで、実際にどんなものがつくれるか試しに作ってみました。

クルッと回るボタン

ホバーすると、くるっとなります。

※このボタンで用いているtransform-style: preserve-3dは、IE10/11では非対応となっています。

perspectiveの値が大きいほど、要素から遠い位置から見ていることになるので、回転する際の奥行きの距離が短く見えることになります。

f:id:beinto:20161223221245g:plain

奥から入ってくるサイドバー

いわゆる「off-canvas menu」や「drawer menu」と言われるものでも、perspectiveプロパティを使うことでリッチな演出になりえます。

奥の方からぱたんとスクリーン上に入ってくるようなアニメーションを実装することができます。

スクロールによる視差効果(パララックス効果)

perspectiveプロパティを使うことで、よくみるパララックス効果を作ることができます。

JavaScriptを書く必要は無いですが、今回はdebug用の横からの視点を見せるためにJSを使用しています。
CSSにかかれているtransform-style: preserve-3dも同様です。

ネコかわいい...

左上のデバッグモードをクリックすると、レイヤーの重なりを横から見ることができます。

f:id:beinto:20161223221418p:plain

また、値とレイヤーの位置を調整することで、Skyworksのような背景に奥行きの出た演出も可能になります。

値を変えることで空間を横断させる

JSを使うことで、空間を横断するような演出も可能になります。

学校に集う学生たちです。
左上のバーを操作することで、perspectiveの値を調整することができます。

指定方法

前章のコードを読んでくださった方はお気づきかと思いますが、perspectiveプロパティは、立体的に見せたい要素の親要素に指定します。

例えば立体のダイスを作る場合、下のようにマークアップしたとして...

<div class="dice-box">
  <div class="dice--1"></div>
  <div class="dice--2"></div>
  <div class="dice--3"></div>
  <div class="dice--4"></div>
  <div class="dice--5"></div>
  <div class="dice--6"></div>
</div>

perspectiveは.dice-boxの方に記述します。(ダイスを作るCSSは省略します👸)

.diceに、transformZscaleを指定すると、立体的なダイスを作り上げることができます。
(裏面が表示される場合は、transform-style: preserve-3dが必要です。)

.dice-box {
  perspective: 100px;
}
%dice {
  /* ダイスを作るためのCSS */
}
@for $i from 1 through 6 {
  .dice--#{$i} {
    @extend %dice;
    /* 各目を作るためのCSS */
    @if $i == 1 {
      transform: translateZ(-100px) rotate(90deg);
    }
    // ...
  }
}

ブラウザ対応状況

perspectiveプロパティ便利そうだけど、実際どのブラウザでも使えるの?」
と気にするのが、昨今のフロントエンジニアの常だと思います。

Can I Useのtransform3dのセクションによると、

  • PCブラウザ: IE10以上
  • Android OSの標準ブラウザ: Android OS 3以上

で利用可能となっています。十分利用できる範囲だと思います。

ただし、併用して使われることのあるtransform-style: preserve-3dIEでは非対応となっています。

気をつける点など

perspectiveの値は0より大きく、%ではない単位をとる

仕様として書かれています。

Where values must be positive.
CSS Transforms Module Level 1より

%は基準とする尺度がないので納得です。

scaleの値によっては画像がボケるので注意が必要

perspectiveプロパティでパララックス効果を実装しようとする場合には、scaleの値を調整する必要があります。
しかし、scaleの値を1未満にした場合、IE/Edgeだとbackground-imageに指定した画像がボケて見える現象が発生します。
これはIE/Edgeの画像のレンダリング形式による問題なので、対策を別途考える必要があります。

さいごに

perspective プロパティを使ってウェブサイトをどんどん作っていきましょう 👸

最後まで読んでいただき、ありがとうございました。

参考文献

明日は...

次回 Tech KAYAC Advent Calendar 2016 最後の記事は、ISUCONでもご活躍されている @fujiwara さんです!

【Unity】AssetBundleの概要

AssetBundleの概要

はじめに

こんにちは、Unityエンジニアの清水です。
この記事はカヤックUnityアドベントカレンダー2016の23日目の記事になります。

今日はAssetBundleの概要についてお送りします。

AssetBundleとは

AssetBundleは複数のアセットを1つのファイルとして書き出したもので、ランタイムで内部のアセットを読み込むことができます。
主に、追加コンテンツの配信のために使われます。
公式ドキュメント

導入目的

前項の通り、AssetBundleを使うことでアプリのバージョンアップなしでアセットを追加、更新できます。
キャラクターやアイテムなど、運用を続けていると自然と増えていきますが、その度にアプリのバージョンアップが必要になると運用がだいぶ難しくなります。
そこで、そのようなアセットはAssetBundleから読み込むように作っておくことで、コンテンツ追加を柔軟に行うことができます。

もう1つのAssetBundle導入目的として、アプリ本体の容量を減らすということがあります。
App Store や Google Play ストアではwifiを使わずキャリア回線でアプリをダウンロードできるサイズに制限があります。
そのサイズ(2016年12月時点では100MB)内に収めるため、容量の大きいアセットをAssetBundleにしてアプリ起動後にダウンロードさせます。

AssetBundleは一度ダウンロードさせたら端末のディスク上にキャッシュしておき、そのAssetBundleが更新されるまでは再ダウンロードさせないのが一般的です。

対象のアセット

ほとんどのアセットはAssetBundle化可能です。
その中でも、更新頻度やアプリサイズへの影響的に、バナーやアイテム画像などのテクスチャ類をAssetBundleで配信することが多いです。
他にサウンドやprefabなどもよくAssetBundle化されます。
ただし、iOSのAOTのため、スクリプトはAssetBundleに含めることができません。
スクリプト本体を含めることはできませんが、prefabやシーンに含まれるMonoBehaviourやScriptableObjectに関しては、アプリ本体にもそのスクリプトが含まれていれば使用可能です。

プロジェクトへの導入フロー

プロジェクトにAssetBundleを導入する際の手順を追いつつ、各段階での注意点などを解説します。

1. ビルド、配信、ロード、バージョン管理、運用方法などの検討、設計を行う

AssetBundleをビルドしたりロードしたりするAPIは用意されていますが、実際にプロジェクトで使うには仕組みを整えたりルールを決めたりする必要があります。
できるだけ自動化して、AssetBundleの追加や更新にかかるコストを減らすことが重要です。
Unity5.3以降を使っているなら、AssetBundleの圧縮形式はファイルサイズとロード時間のバランスが良い LZ4 がオススメです。

2. ビルドスクリプトの実装

AssetBundleを出力するためのスクリプトを用意します。
Unity5から、インスペクタでAssetBundle名を設定して BuildPipeline.BuildAssetBundles を実行すれば簡単にビルドできるようになりました。
f:id:shimiu:20161221110829p:plain
ビルド対象をコードから指定することも引き続き可能です。

AssetBundleにすることが最も多いであろうテクスチャはエンジニア以外が用意することが多いので、あまりUnity上で操作しなくても追加できるようにしておくと良いでしょう。
例えば、特定のディレクトリに配置するだけで良いようにしておくと、デザイナーだけで作業が完結できるかもしれません。

また、アプリ本体のプロジェクトとは別にAssetBundleビルド用のプロジェクトを用意することが多いです。
プロジェクト内に大量のアセットの存在するとインポート時間が長くなり、作業に影響が出てくるためです。

3. ロードやアンロードを管理するスクリプトの実装

ランタイム側で使用するスクリプトを用意します。
複数箇所から同じAssetBundleへのアクセスがあった場合の制御、解放タイミング、キャッシュからの取得などを管理する必要があります。
キャッシュに関しては WWW.LoadFromCacheOrDownload を使用すればバージョンの制御くらいで済みます。
ただ、この方法ではキャッシュ削除のタイミングが制御しづらかったり、複数のAssetBundleを並行でロードする場合のパフォーマンスが出なかったりするので、自前で実装する場合もあります。

ここまでが初回導入時に必要になる手順で、以降はAssetBundleの追加の度に発生する手順になります。

4. アセットを用意してAssetBundleをビルドする

2で用意した仕組みを用いてビルドします。
あまりたくさんのアセットを1つのAssetBundleにまとめてしまうと、変更が入った時にダウンロードし直す容量が大きくなるため、基本的には小分けにしたほうが良いです。

5. AssetBundleをサーバに配置する

AssetBundleをダウンロードできるように、サーバ上に配置します。

6. サーバから配信するAssetBundleのバージョン情報を更新

AssetBundleのキャッシュの制御のために配信するバージョン情報の更新を行います。
手動で管理するのは大変なので、自動で更新される仕組みを用意しておくと良いでしょう。
ビルドのたびにインクリメントされるようにする、対象ファイルのgitのコミット回数を使う、などが考えられます。
jenkinsなどを使って、4からここまでのフローを自動で行われる仕組みを構築しておくのが望ましいです。

7. 動作確認

アプリ本体の開発と同じく、実機での動作確認は必須です。
iOSとAndroidでAssetBundleは別ファイルになるので、それぞれ確認するようにしましょう。

おわりに

今日はAssetBundleについての導入的な内容をお送りしました。
明日はp_chinによるビルドとリリースに関する記事になります。