作るのは数字だけじゃない / デジタルハリウッド
作るのは数字だけじゃない / デジタルハリウッド
2018.01.26
#121
それいけ!フロントエンド

株式会社DDホールディングスのサイトを制作したので、フロントエンド的振り返りをしてみた

まろ

こんにちは。まろCです。
今回は制作した案件について、フロントエンドでどう実装したか振り返りを行いたいと思います。

お客様は株式会社DDホールディングス。ホールディングス化する際のwebサイト制作のお手伝いをさせていただきました。

リリースしました

2017年12月4日に、ティザーサイトを経て本サイトが公開されました。
https://www.dd-holdings.com/

スクリーンショット 2017-12-12 13.23.09

外食産業で一部上場をしている会社で、飲食だけでなく、BAGUS(バグース)などのアミューズメント施設やカワイイモンスターカフェなどのコンセプトショップも展開し、オープンイノベーション企業として500店舗以上を有する、勢いのある企業です。

振り返り

さっそく、技術面を振り返っていきます。

トップページは各セクションをブラウザの画面いっぱいに配置する、いわいるfitなデザインです。スクロールやタッチイベントに合わせて次のセクションへとアニメーションしながら遷移します。

https://gyazo.com/57fe2ea9ed2b7c6b34ddd3554b8e3209

画面遷移はpjaxを使っています。ここでも遷移先のページのコンテンツを読み込みながら、アニメーションをつけて遷移させています。

今回は主にトップページの話になります。

スクロール&タッチイベントの制御をどう実装したか、遷移時のアニメーションをどう実装したか振り返りながら、新コピーであるDynamic&Dramaticをサイト上で体現するためどうしたかを少し書いていければと思います。

lodashでのスクロール制御

解説

lodashのthrottleメソッドが優秀です。連続して発生するイベントをnミリ秒後まで間引くことができるこのメソッドで、スクロール及びタッチのイベントを制御しています。

スクロールの例で言えば、一度スクロールした瞬間、2000ミリ秒はスクロールを受け付けない処理になりますので、最初の一回で上下どちらの方向へのスクロールか判定して、遷移の処理へと進みます。本来であればtimerを使って自ら連続して発生するイベントを、簡単に記述できる点、最高です。

判定だけに限れば、以下の記述量で大丈夫です。

this.touchMove = 0;
this.$main.on('touchstart.homeScroll', _.throttle((e)=> {
            this.touchMove = e.originalEvent.changedTouches[0].pageY;
        }, 100, {trailing: false, leading: true}));
        this.$main.on('touchmove.homeScroll', _.throttle((e)=> {
            e.preventDefault();
            if(this.touchMove < e.originalEvent.changedTouches[0].pageY) {
                this.scrollUp();
            } else {
                this.scrollDown();
            }
        }, 2000, {trailing: false, leading: true}));
        this.$main.on(this.mousewheelevent+'.homeScroll', _.throttle((e)=> {
            e.preventDefault();
            if (e.originalEvent.deltaY < 0 || e.originalEvent.wheelDelta > 0) {
                this.scrollUp();
            } else if (e.originalEvent.deltaY > 0 || e.originalEvent.wheelDelta < 0) {
                this.scrollDown();
            }
        }, 2000, {trailing: false, leading: true}));

苦労した点

各ブラウザで、e.originalEventで取得できる上下方向を判別するためのキー名称が違ったため、あわせて設定しました。後述する遷移アニメーションの終了と合わせた間引き間隔調整のミリ秒数を設定しなければならないので、最後の調整まで微調整しながらイベントを受け付けない間隔を見つけていきました。

改善点

タッチイベント部分は、もしかしたら、touchstart、touchmoveの調整を行うことで、より自然なスクロールを実現できたかもしれません。どのイベントにも使えるので、2重クリックの防止など誤動作を招く恐れのある操作には今後取り入れていきたいです。

CSSアニメーションで動かす

解説

いつもはTweenMaxを使って動かしているのですが、アニメーションをkeyframeで作成して、jsからクラスの付け替えで実行する方式を採用しました。

個別に動かす対象が多いのと、CSSでも結構自由に動かせるので、重さなど考慮した上で、この選択にしました。また、今回はイージングにもこだわりました。お客様から連想される、エネルギッシュで大胆な動きをめざして、操作感は気持ちよくすることに挑戦しました。

cubic-bezier(0.740, 0.015, 0.465, 1)

このイージングです。
また、アニメーションの移動距離を長めかつ、奥行きをもたせることで、よりコンセプトを体現できるようにしました。

基本的には、下から入ってくる動き、上から入ってくる動き、上に出ていく動き、下に出ていく動きのアニメーションを作って、背景とコンテンツに出て行けと指示しつつ、それが終わったら入ってこいと指示しています。

&.is-in-from-bottom {
  animation: in-from-bottom $time_section $ease forwards;          
}
&.is-in-from-top {
  animation: in-from-top $time_section $ease forwards;
}
&.is-out-to-top {
  animation: out-to-top $time_section $ease forwards;
}
&.is-out-to-bottom {
  animation: out-to-bottom $time_section $ease forwards;
}

上記のような処理を、動かしたい対象分、CSSに記述しています。

苦労した点

背景のシャッターは、入ってくるアニメーションを設定するときに、animation-fill-modeをbothにしないとSafariで動かない現象が発生しました。
また、以下のように初期値を入れておかないと、うまく実行されませんでした。

>&.is-page-transition-end {
  animation: pageTransitionEnd $time $ease both;
  transition-duration: 0s;
  transform: scaleX(1) scaleY(1);
  transform-origin: right center;
}

改善点

クラス付け替えの監視をsetTimeoutで行っていたので、もっといい方法があったと思います。keyframeが大量になり、どのSassファイルに分割するのがやりやすいか答えを見つけられなかったので、今後改善していきたいです。

まとめ

いかがでしたか。制作を振り返ることで次の目標が見えてきました。今後もいいものを作っていきたいです。

それでは。

. . .