推しの非公式3周年記念企画に参加した話
↑このサイトの制作に参加しました!
制作チーム
ファンの有志を募って制作する形だったので普通にウェブサイトを制作する時のチームとは少し違ったと思います。企画、エンジニア2名、イラストレーター、モデラー、既存のファンサイト作者の方などが集まって作りました。
フロントの構成
フレームワークにVue、サーバにnginxを利用して制作しました。インフラにECSを使用したのでサーバの設定やCIなどももうひとりのエンジニアの方に教わりながらやりました。
制作ステップ
企画の方がおおまかなページ構成を決め、エンジニア組で大枠を制作しました。その後、細かいデザインをイラストレーターの方に作ってもらったり、機能を足したりバグを直したりしながら完成させました。はじめは私一人でフロントを担当する予定だったのですが、もうひとりの方に手伝ってもらいなんとか完成までたどり着けました。
ちょっと大変だったところ
フロント視点で作るのが大変だったところについて語らせてください。
OGP
metaタグをページに埋め込んでおくことでTwitterなどにリンクが投稿されたときに画像や説明を表示させられます。これをOGPといいます。VueはSPA(Single Page Application)といって1つのページしか存在せず、そのページ上をjavascriptで書き換えることで複数のページがあるように見せています。OGPはbotがページを取得し表示しているのでプログラムが走らず、パスによってOGPの内容を変えることができません。
今回の企画ではモザイクの一要素をtwitterで共有しやすいようにパスによって違ったOGPを返す必要がありました。下の画像は一モザイク要素を共有したときの表示です。モザイクページに飛びますがリンクについたクエリに応じて表示内容が変わるようになっています。
これを実現するために、「SPAのOpen Graph Protocol 対応について。さらにCloudFrontを経由した場合についてのつらい話。」を参考にしてtwitterbotやdiscordbotからのアクセスはAPIサーバーにプロキシするようにしました。
結果的に、SPAでない通常のサイトではできないクエリに応じてOGPを変えるということができました。OGP用のHTMLを返すAPIの制作やAWSの設定はもうひとりのエンジニアの方にすべてやってもらったし、nginxの設定のうまく行かない部分の洗い出しもやってもらったので感謝しかないです。
モザイクアート展示ページ
あとから知ったんですけどこういった巨大な画像をズームし、必要に応じて段階的部分的に高解像度画像を読み込んでいくやつをDeepZoomというらしいです。こんなやつ。そんな名前も知らなかったのでライブラリなどを使わず一から作ってしまいました。ズームや画面操作の実装が簡単かなと思いSVGのviewboxを活用しながら制作しました。ズームを表示している画像全体のサイズを変えるのではなく、viewboxをカメラのように扱って画角を狭くする感覚で実装できたのがやりやすかったです。
実装にあたって大変だったところは二箇所あって、1つ目はタップ操作です。
マウス操作は左クリック、右クリックなど入力がはっきりわかれていますが、スマホでの操作はすべて指で行われ、その指の軌跡、速さなどからピンチやスワイプ、タップを判定しなければいけないのがバグの温床となりました。タップ操作系のライブラリもあるにはあったのですが、ドラッグするときに指にモザイクアートがピタッと追従してほしいといった細かい要求が多いのと、Vue3で使いやすいライブラリが少なかったので基本のタッチイベントを拾って頑張りました。が、不自然な動きも多くなってしまったと思います。ユーザーに違和感なく自然に操作させているスマホ、本当にすごい。
2つ目は表示する要素が多すぎて重たくなってしまったことです。
低解像度の画像をフロント側でcanvasを利用して4*4をまとめて一つの画像として保存し、それを表示させることで表示する要素数を削減しました。バックエンドで固めてしまうのもありなのですが、モザイクアートの並べ方をたくさん用意しランダムで切り替えるという話があり、その場合用意して置かなければならない画像が多くなるということでこのような実装となりました。
線
透過動画を上から載せたかったのですが、WEBで透過画像を流す方法が有料のものしか見つかりませんでした。線のアニメーションの進行度に応じてモザイクをスムーズに表示したいのもあり、Adobe Animateでアニメーションを作成しhtmlで出力しました。ブラウザの大きさに合わせてCSSで大きさを変えたかったのでiframeタグ内にアニメーションを設置しました。先程も書きましたが、アニメーションの進行度に応じて処理を行いたかったので、コマごとにMessageイベントを発火させる処理を追記しました。
モザイク表示が重たく、アニメーション表示中にすべてを表示するとカクついてしまいます。ので、アニメーション中に奥がチラ見えするタイミングで元絵を表示し、アニメーションが完了した後に他要素を表示するようにしました。iPhoneだと相性が悪く表示できなかったり、慣れないソフトを使うことになり大変だったのですがシオンちゃん本人にも褒めてもらえたので作ってよかったです。
感想
自分ひとりじゃできない要素がたくさんありましたが、シオンちゃんへの思いでメンバーが集まり、1つのものを作り上げられたことがすごいよかったです。分業ってコミュニケーションだとか思想の衝突だとか色々大変なところもあると思うのですが、企画コンセプトの強固さとシオンちゃんへの思いで纏まれたと思います。
あとは、開発での学びなのですが、途中で機能を足したりということが多かったのでコードをきれいに書く大切さがわかりました。モザイク部分をいい感じに分離することができず、1つのコンポーネントでかなりの行数になってしまったのでそこは何とかできなかったかなぁと思います。
色々な学びもありましたし、一緒に作る楽しさもありましたし、何よりみんなの思いを伝えるお手伝いができ、シオンちゃんに喜んでもらうことができてよかったです。