こんにちは、フロントエンドエンジニアのくりちゃんです。LIGではフロントエンドとアニメーションの実装をしています。
LIGで働いて2年目になった頃、ある程度のフロントエンドのスキルは身についたし、アニメーションも実装できるようになったから、そろそろポートフォリオサイトを作りたいなぁと思いたち、先日ようやくリリースすることができました。
https://twitter.com/AAA00832745/status/1538860217517019136?s=20&t=jt8pWBQTuNOmk6EUVonUvg
 
思いのほか反響があり、三大Webアワードのawwwards CSS Design Awards FWA を受賞することができました。とても嬉しかったです。
この記事では制作を振り返りつつ、技術周りのことや、動きのあるWebサイトを作る意味を書いていきたいと思います。
目次
ポートフォリオサイト制作過程
自分らしいデザインを目指し、デザイナーさんをアサイン
ポートフォリオサイトを作ろうと思ってから、デザインを自分でやるかずっと迷っていたのですが、元LIGのデザイナーさんにポートフォリオサイトの話をしたらバイブスが合って作ってくれることになりました。
このデザイナーさんとはLIG在籍時代に一緒によく案件をやっていて、以前自己研鑽で制作していたデザイン案がとても好みだったのでそのテイストにして欲しい、パーティクルを使って欲しい、アワードを取れるクオリティにして欲しいと伝えました。
今振り返るとすごくふわっとした要求だったと思うのですが、そこから載せたいコンテンツやページ数を相談して、約一ヶ月ほどでデザインを完成させてくれました。
動きのあるWebサイトを作るうえで、難しいのがデザイナーさんとの動きのイメージの共有です。デザイナーさんからもらうデータは静止画なので、実装をするエンジニアは頭の中で動きをイメージしないといけません。
静止画と一緒にテキストベースの動きの指示書をもらったあと、オンラインMTGで詳細なアニメーションの指示をPSDでオブジェクトを実際に動かして、イメージを伝えてもらいました。その後は都度細かくイメージを擦り合わせていったり、実装過程で、別の動きのほうが良さそうだったら提案したりしています。
また、デザインを共有してもらった時点で、今の自分の技術レベルでは実装できない、がんばれば実装できそう、実装できるけど時間がかかると言った懸念点は、デザイナーさんにもなるべく共有するようにしています。
非同期遷移と慣性スクロール
アワードを受賞するサイトで多く見かけるのは、非同期遷移と慣性スクロールです。ポートフォリオサイトではページ遷移の演出やパフォーマンスにこだわろうと思っていたので、絶対に実装しようと思っていました。
非同期遷移は、サーバーから非同期に情報を取得してくるので、ページ遷移が高速で、遷移の際の動きも自由につけることができます。慣性スクロールはデフォルトのスクロールに比べてゆったりとしたスクロールになるので好みは分かれがちです。
最初はbarba.jsで非同期遷移を実装をしようと思っていたのですが、barba.jsはmetaタグ周りなどの細かいところは自分で実装しないといけない部分がネックだったのと今後のトレンドを考慮して、Nuxt.jsで実装を挑戦してみることに決めました。
慣性スクロールはLocomotiveScrollとASScrollでどちらを採用するか迷っていたのですが、覚えることが少ないのとWebGLとの親和性が高いことを考慮してASScrollにしました。
Vue.js/Nuxt.jsを触り始める
当時は流行りのJavaScriptフレームワークを一度も触ったことがなく、むしろピュアなJavaScriptが一番好きだなぁと思っていました。そんな状態からVue.js/Nuxt.jsは書籍や動画教材などを使用して学習していったのですが、Vue.js/Nuxt.jsはシンプルで覚える知識も少ないので一通り学習を終えた頃には、つまづくことなく頭に入っていきました。
非同期遷移もNuxtLinkコンポーネントを使用すると簡単に実現ができます。
<nuxt-link to="/about">about</nuxt-link>
非同期遷移以外にも、Nuxtを立ち上げた時点で開発環境が既に整っている点や宣言的に書ける点など、開発体験がとても良いです。
Three.jsとGSAPでアニメーション実装
Vue.js/Nuxt.jsを一通り覚えた後に、ポートフォリオサイトの実装をスタートしました。マークアップと並行してアニメーションの実装をしていくのですが、アニメーションの実装をするときにいつも使用しているのが、Three.jsとGSAPです。
Three.jsはWebGLを簡単に扱えるようにしたライブラリです。ただ、Three.jsでWebGLを扱いやすくしても、とても難しいです。なので、WebGLを使用するのはそれ以外で動きを表現できないとき、もしくはパフォーマンスが著しく落ちるときに限定して使用するようにしています。正直、CSSで表現できるなら、なるべくWebGLは使用したくないです。
ポートフォリオサイトではトップページのピックアップ部分のメタボールをWebGLで実装しています。メタボールはSVGやCSSのfilterを使用すれば実装できると思うのですが、パフォーマンスを考慮してWebGLで実装しました。
背景のパーティクルもWebGLで実装しようと思ってたのですが、WebGLにパーティクルの衝突計算を上手く落とし込めなかったので、Canvas2Dで実装しました。
アーカイブページのカードが湾曲する動きもCSSでは実装できない動きなので、WebGLで実装しました。DOMをtransformで動かして、その座標を毎フレーム取得してWebGLで描画しています。
GSAPは高機能なアニメーションライブラリです。DOMのアニメーションを簡単に実装することができて、スクロールに連動した複雑なアニメーションも実装することができます。
先ほど、DOMのアニメーションを簡単に実装することができると言ったのですが、GSAPはJavasScriptのオブジェクトも動かすことができます。
let object = { value : 0 };
gsap.to(object, {
duration: 1.0,
ease: "power2.out",
value: 1.0,
});
トップページのピックアップ部分はホイールの上下の操作で前後のシーンに切り替わります。メタボールとパーティクルはWebGLとCanvas2Dで描画していると説明しましたが、前後のシーンに切り替わるアニメーションはGSAPでキーとなるJavasScriptのオブジェクトを動かすことで実装しています。
ピックアップ部分は一番力を入れた部分だったので、実装も苦労しました。ここはある一定のラインを超えるとスクロールをジャックして、強制的に位置を動かしてスクロールの操作も禁止させるのですが、ブラウザのネイティブな挙動に逆らう挙動なので、PCでうまく動いてても、SPで上手く動かなかったりして、最後まで調整を繰り返していました。
遊び心のあるインタラクション
サイト共通の処理で線になっている箇所はマウス位置に応じてたわむ実装、カードの箇所はホールドで移動、吹き飛ばせるような実装をこちらもGSAPを使用して実装しています。見る人がつい触ってみたくなるような仕掛けを色々な所で仕込んでいて、クオリティを一段階上に引き上げてくれたと思ってます。
ポートフォリオサイト制作で気をつけたこと
気持ちの良いアニメーションを目指して
アニメーションを実装するうえで、いつも悩むのがアニメーション時間とイージングです。デザイナーさんがデータを動画で作成してくれれば、その通りに作れば良いのですが、静止画とテキストベースで指示されることが多いです。なので、この部分は実装するエンジニアのセンスが多少問われる部分なのかなと思っています。
よく議論されていることだと思いますが、ボタンやメニューなどのUI周りは、ユーザーに速く反応を返したいので、アニメーション時間を短くして、イーズアウトを使うようにしています。
拡大・縮小/移動/回転などのアニメーションはイーズインアウトを使うようにしています。上手く言語化できないのですが、機械のような動きではなく、生きているような心地よい動きになると思います。
アニメーションの時間はなるべく統一するようにしていて、ベースは0.5~1.0sの間で設定して、そこからショート、ロングの時間を作って変数で管理するようにしています。
とは言え、デザインやどう見せたいかによって、アニメーション時間とイージングはまったく変わってくるのでデザイナーさんと相談しながら決めていけるのが一番良いのかなと思っています。
また、アワードを受賞するサイトを見ていると、1画面を1枚絵として見た時に止まっている時間がなく、何かしらのオブジェクトが動いているケースが多いです。何かをクリックしたとき、スクロールしたとき、ページ遷移するとき、マウスを動かしたとき、何かしらの反応が返ってきて、スルスルとついつい色々なページを見てしまいます。
Webサイトを作るときは全体を通して、止まっている時間がない実装をいつも心掛けています。
ランダムではなく、良い感じのランダムを作る
よくデザイナーさんから、ここはランダムな感じで……とお願いされることが多いのですが、デザイナーさんが求めているのはただのランダムではなく、良い感じのランダムを求めているんじゃないかと思っています。
例えば、0以上1未満の乱数を5つ作るとして、JavaScriptのMath.random()を使用したら、要件は満たせると思いますが、場合によっては偏った乱数が生成されます。
[ 0.9, 0.9, 0.9, 0.9, 0.9 ]
自分が考えているデザイナーさんが求めていると思うのは、こういう乱数です。
[ 0.2, 0.6, 0.4, 0.8, 0.5 ]
偏りがなくまばらな、いわゆる良い感じの乱数を常に求めているんだと思っています。
偏った乱数がグラフィックに落とし込まれると、偏ったグラフィックになってしまうので、良い感じの乱数をあらかじめ作っておいて、それを常に使用して、良い感じのグラフィックになるようにしています。
x: { 'pc' : 110, 'tab' : 80, 'sp' : 55, }, // X座標
y: { 'pc' : 160, 'tab' : 120, 'sp' : 80, }, // Y座標
r: { 'pc' : 60, 'tab' : 50, 'sp' : 40, }, //半径
rand: { 'pc' : 0.62, 'sp' : 0.31, }, //乱数
ポートフォリオサイトでもパーティクル一つひとつに、あらかじめ座標、半径、乱数を指定しておくことで、常に良い感じのグラフィックになるようにしています。
アニメーションとパフォーマンス
アニメーションを実装するうえでパフォーマンスは切っても切り離せない問題だと思います。パフォーマンスについては正直教えて欲しいぐらいなのですが、基本的なことで一つだけ意識しているのは、見えていないときは動かさないようにすることです。
ループで常に動く箇所は、Intersection Observer APIを使用して画面外だったときには動きを止めるようにしています。個人的に、パフォーマンスは細かいことの積み重ねで良くなっていくと思っているので、細かいところも手を抜かないように気をつけています。
動きのあるWebサイトを作る意味とは?
Webアニメーションは見る人によってはいらないとか邪魔だとかいう意見もあると思うんですが、適切でクオリティの高いWebアニメーションはWebデザインの品質を向上させ、もっと続きを見たいと思わせることのできる有効な手段だと思っています。
また、Webアニメーションはどう見られたいかを助ける役割があるのかなと思っています。例えばターゲットが富裕層の企業だったら高級感が感じられる演出を、ユーモアのある企業だったら面白い演出を入れるなど用途は様々あると思います。細かい面だと表示演出の順番によって視線誘導の手助けになるとも思います。
適切なWebアニメーションを入れることでユーザーの視線の動きから心まで動かせられると信じ、今後も引き続き邁進していこうと思います。
使用技術
Front End
Framework : Vue.js, Nuxt.js
Library : Three.js, GSAP, ASSCROLL
Back End
Cms : microCMS
ーーー
また、LIGが運営するスクール「デジタルハリウッドSTUDIO by LIG(デジLIG)」では、Webクリエイターになりたい方の支援をしています。これからWebクリエイターを目指したい方は、ぜひチェックしてみてください。
LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。