開発記録

2023年 3月31日 更新

ご挨拶

初めましての人も、知り合いの人もこんにちは。
本WEBサイトの企画、制作をした染井です。

まずは、この開発記録をご覧いただいている皆さん、ありがとうございます。
需要あるかわかりませんが、息抜き程度で書いてみた次第です。 WEB開発経験は少ないので、あまり大きなことは言えませんが、WEB開発経験者はちょっとだけ参考になるかもしれません。多分。
また、WEBの知識がない方でもある程度読めるように、専門的すぎることはなるべく省いて書きましたので、ご安心ください。

ちなみに、サーバーにアップロードするもので大掛かりなものとしては、今回で2作品目となりました。
前作はこちら(2024年10月ごろに消滅するので、この機会にぜひ!) → 多摩美術大学グラフィックデザイン学科卒業制作展2022

今回は、「3Dライブラリ THREE.js」、「アニメーションライブラリ Tween.js」、「CSS mix-brend-mode & filter」、「文字化け」、「隠し要素」、「振り返り」の6本立てでお話ししていこうかと思います。
特に3Dには翻弄されまくったので、結構長くなっちゃいました...
スマホ版とデスクトップ版で仕様が違う理由とかもここにあるので、気になった方はぜひ。
また、隠し要素が気になる人は、そこまでスクロールしてください。


なお、本サイトの更新履歴等は以下の通りです。

2023年 1月23日 制作開始
2023年 2月12日 公開
2023年 2月23日 グッズ公開
2023年 3月31日 ムービー等追加

I ─ 3Dライブラリ THREE.js

THREE.jsとは?

「THREE.js」って何??となると思いますが、これは、3Dが扱えちゃうJavaScriptライブラリです。
比較的手軽に3D空間が描画できる代物で、使い方を学びつつ、今回のような簡単な立方体であればなんとか制御できました。
デスクトップで見てくれた方なら言わずともわかると思うのですが、背景とEXHIBITORSでは、これを利用しています。
スマホ版でしか見てない人は、ぜひPCでも見てみてください。
使ってみたい、と思った方は、ネットで調べれば意外と豊富にサンプルやら情報が転がっているので、ぜひ。
ちなみに自分は大学の図書館でそれの本を借りましたが、あまり役に立ちませんでした。(古いからかな??といっても2016年だけど、、)

背景での利用

背景では、デバイスの画面幅と高さを取得した後、立方体をどのくらいの量生成するかを計算し、量産しています。
生成の順序についてより詳しく知りたい人は直接聞いてください。(いないと思うけど)

苦労したこと一つ目は、生成数と位置が想定となかなか合わなかったことです。
一つずれて生成されたり、なぜか同じ位置にいくつも生成されたり、存在しないはずの立方体が出現したり...。
まあ、もちろん全部自分が書いたコードが悪いのですが、(もう少し詳しく書くとfor文での繰り返し中の条件分岐やらがミスってた)綺麗に上手く生成されるまで結構時間かかりました。

苦労したこと二つ目は、上下左右で同じ作者の立方体を生み出さないようにしたことです。
どこに誰のXの立方体が生成されたかを記録しておき、ランダムで選ばれた値が被っちゃったら再抽選...って感じでやってたのですが、その上下左右で被ってるかのif文を書くのがなかなか大変でしたね、、
しかもなぜか、論理演算子(または、とか、かつ、といった条件を指定するやつ)で、または(||)、にするべきところを、かつ(&&)、にしてた時があって、これはイージーミスと思いました。

苦労したこと三つ目は、カメラ制御です。
立方体だけじゃなくて、カメラ操作も指定しますが、これがなかなか数学的だったので、ネットに転がっているサンプルをちょっといじって、今回用に改造しました。。
今見ても、やっぱりなんでこれでこうなるのかがいまいちわからない。数学もっと勉強しとくべきだったと、プログラミング始めてから割と後悔してます。
ちなみに、PC版で右下の立方体アイコンをクリックすると、背景を見るモードに入るのはお気づきですか??
その際に、カメラも動きやすくなってます。やっぱり背景見せたいので...!!

苦労したこと四つ目は、スマートフォン版での処理落ちです。
実は、最初はスマートフォンでもガッツリ3D使おうと思ってました。
で、サーバーにアップロードしてみて、自分のiPhoneで接続してみたら...
「問題が発生したためページを再読み込みしました」的な表示がでて、なんでだろうと思い調べたら、処理落ちだそうです。
今思えばそりゃそうだろう、って感じですね。だって開発中にずっと動かしてたらPCでさえもカクつくんですもん。
スマートフォンが耐えられるわけがない。
処理を軽くする方法として、フレームレートを落としたり、解像度を下げたりと色々試したけどどれもだめでした。
ちなみにスマートフォンでは 3×3の9個でギリ表示はできる感じでした。
表示できるだけであって、固まりまくるので実用には及ばない...
というわけで、急遽、スマホでは完全2Dにすることにしました。パタパタと背景が変わる感じになってます。
でもやっぱり3D使った後の2Dは楽ですね。大体一日かからずに実装は完了しました。
我ながらwebスキルが上がってきている気がする。

苦労したこと五つ目は、2/3ぐらいの確率で立方体が表示されない不具合の解決です。
プレビューで開いても、なぜか背景グラデーションだけしか映らない状態が多く、リロードを繰り返すとたまに表示される感じの症状に陥りました。
これの解決に二日ぐらいはかかりましたね。修正時もはっきりとなぜかがわからなくて、もう一回再現しようと思っても思い出せず、、なんでだっけ。
htmlで該当scriptを入れる順番を変えたことが解決法だった気がしたけど。。。
とにかく、ログではしっかりと立方体が生成されているのにもかかわらず見えないという、エラーの吐かないバグに腹が立っておりました。
javascriptは繊細に扱わねば...。

EXHIBITORSでの利用

EXHIBITORSでも立方体を引き続き利用しているわけですが、質感が背景のものと違うことには気づいたでしょうか?
背景のものは、マットな感じになってますが、こちらの立方体は少し光沢を感じます。
回転するので、てかてかしている方がいいかなと。
というか、このマテリアル設定が意外と面白いんですよ。
光をどのくらい反射させるかとか、メタリックにするかとか、色々設定できて奥が深いです。

立方体には、各担当色も着彩されていますが、これは元の画像を加工したわけでもなく、マテリアルに色を与えたわけでもありません。
色のついた光を当てているのです。
ちなみにライトもいくつか種類がありまして、太陽みたいな一定方向から照らすものもあれば、均等に全空間を照らしてくれるもの、スポットライトとかもあります。
今回は色付きのスポットライトと、全空間を照らすライトを併用していい感じにしました。
マテリアルに色をつけるのが一番簡単なのですが、色がつきすぎて元画像がわかりにくいというデメリットがあったので、こちらを採用しました。

あとはクリック判定ですね。
これもなかなか苦労しました。
オブジェクトのクリック判定はネットにゴロゴロと転がっていたのでそれを拝借。
最初はアイソメトリックカメラ(等角投影図法のもの)を利用してたのですが、なぜか座標がズレて合わなかったので再度ネットの海へ。
調べてもわからなかったので色々試したら、反応する座標が、パースペクティブカメラのものなのでは?!と気づき、カメラをそちらに変更したら無事解決。
座標を等角に直す方法もあったのだろうけど、面倒なのでこの解決法でいきました。

ちなみに、PC版では、立方体の下にある名前も、実は立体で生成しています。
カーソル合わせると立方体同様に回っちゃうんですよね。直そうと思ったけど、これはこれで面白いので放置。
名前をなぜ立体で置こうかと思ったのかというと、立体の生成位置とhtmlでの文字の位置が、CSSで上手く合わせられなかったためです。
だったらオブジェクトとして立方体のすぐ下においちゃった方が早いなと思ったわけですが、そうでもありませんでした。

まず、文字を生成するために、よく知らないmoduleタイプのjavascriptを利用しなければならないところがきつかったです。
で、よくわからないエラーがログに大量出力され...。
今もエラー出るのですが、これは問題ないエラーっぽいです。それがわかるまでにも時間がかかった。
ひとまず、moduleでのimportやexportといったデータの受け渡し?を理解するにはまだまだ時間がかかりそうです。
これでちょっと独学の限界を感じる問題でした、、。

少し脱線しますが、スマホ版のEXHIBITORSでは、立方体の展開図を採用しています。
デスクトップ版での立方体に対応させたいなと思って、展開しました。
XPANDだけに.........
あ、展開図は10種類のパターンからランダムに選ばれてます。読み込むたびにパターンが変わるのにも気づいたでしょうか??

Ⅱ ─ アニメーションライブラリ Tween.js

Tween.jsとは?

上に引き続き、「Tween.js」って何??となると思いますが、これは題の通り、アニメーションを指定できる高機能のライブラリです。
今回は、スクロールした時の背景がXPANDするアニメーションと、たまに回転させるアニメーション、カメラの操作をなめらかにする処理、背景色のグラデーション変化に使いました。
普通のHTMLのDOM要素にも使えるっぽいんですけど、ちょっとよくわかりませんでした。
THREE.jsと組み合わせて使えるのがかなり良いですね。

背景での利用

とは言っても、背景でしか使ってないので、そんなに書くことはないです。
立方体を生成した時点でその生成座標を配列に記録しておいて、ついでに移動先の座標も計算で記録しておく。
そしてスクロールで一定の値が得られた時、各立方体に対して、記録しておいた移動先の座標に移動してねっていうTweenアニメーションを実行すればあんな挙動になります。
たまにくるくる回転するやつもTween.jsでやってます。
0.05秒ごとにどれか一つ回転してるんです。結構高頻度。
カメラも同様に、0.05秒ごとにマウス座標を更新し、それに応じてアニメーションさせてなめらかに動くようにしてます。

背景色グラデーションは運良くサンプルが転がっていたので、それを参考にすんなり実装完了。
十六進数カラーコードでアニメーションさせると、いろんな色を経由して大変なことになるので、rgbの値を利用してやると綺麗にグラデーションになる...というところもしっかり書いてあったのが助かりました。

Ⅲ ─ CSS mix-brend-mode & filter

CSS mix-brend-mode & filterとは?

CSSで mix-brend-mode と filter っていうプロパティがありまして。
これが結構便利なんです。
フォトショップで使うような、乗算やオーバーレイなどの合成モードを指定できたり、調整レイヤーの処理(色相彩度、コントラストとか)もできちゃいます。
わざわざフォトショで加工しなくても、これで完結できちゃうという代物です。
で、どこに使われているのかというと...

文字透過

このページのこの文章でも使われていますが、ロゴや文字をくり抜くのに使ってます。
mix-brend-mode : screen を指定してあげるだけで、暗い色が透過されちゃうのはとても嬉しい。
ただ、デメリットとしては、メインコンテンツ全体に適用しないと上手く動いてくれないので、画像やインスタとかの透けさせたくないコンテンツも透けちゃうことでした。
なのでわざわざscreen適用外に置いて、javascriptで後から位置指定してあげてる形にしました。
説明むずかしい。

ドロップシャドウ

スマホ版のEXHIBITORSで、展開図には影を落とさせています。
ただ単に、filter : dropshadow(offsetX,offsetY,ぼかし具合,色) を適用しているだけなんですが、ちょっと工夫した点があるのでそれをご紹介。

デスクトップ版では問題なく表示されるのですが、iphoneのsafariで表示した時に、かなり重くて、正常に表示されるまでに時間がかかる。
ただ単にスマホの性能の壁かな?と思いきや、調べてみると、iphoneでは、filterを何故かGPUを使用せずにCPUで計算してるからだそう。
で、解決法として、filterかけてるクラスに、transform : translateZ(0) を入れてあげると、これまた何故かGPUで計算してくれるそう。
意味がわかりませんが、ひとまずスマホでも正常に表示されるようになったので安心です。

Ⅳ ─ 文字化け

文字化けとは?

説明不要かと思うのですが、
螟ァ蟄ヲ髯「菫ョ螢ォ1蟷エ縺ョ譟謎コ募━蟶後〒縺吶??
こういうやつです。
ちゃんとした日本語文章の成れの果て。

今回は個人ページの文章をjavascriptに書き込んで、htmlに反映させる方式をとったのですが、そのjavascriptで文字化けが発生。
仕組みやら原因やらをお話しします。

文字化けの発生原理

どうやら文字コードが一致しないと発生してしまうようです。
文字コードって?となると説明が難しいので、調べてみてください。
日本語を使用する際の文字コードである、 utf-8 をhtmlのmetaタグ指定しており、それと異なる文字コードの文字を使っちゃうとダメなようです。

文字化けの原因

原因は至ってシンプル。
ハヤシさんの絵文字でした。🌈💖
(ハヤシさんがこれ読んでるかどうかわかりませんが、気にしないでください!というか、むしろありがとうと言いたい。勉強になったので!!)

文字化けの回避法

絵文字を絵文字として書かずに、数値文字参照を利用します。
🌈 は 🌈
💖 は 💖
みたいな感じで書くと、絵文字としてではなくアルファベットとして認識するので、問題なく表示されます。
調べれば、絵文字の文字参照一覧みたいなサイトがあるので、webで絵文字を使う時は、この数値文字参照で書くことを忘れずに...!

Ⅴ ─ 隠し要素

前からやってみたかったんですよね。
隠し要素入れるの。
卒展サイトでも入れたかったのですが、時間がなかったのと、単純に入れていいかが微妙だったのでやめました。
だけど、今回はトップページにて無事に隠れさせてあげることができました。
あなたは見つけられることができるでしょうか...!?
ちなみに、見つかった時は、「おめでとうございます!」みたいなポップアップが出るので、それが出なかったら隠し要素ではありません。

ノーヒントだとほぼ100%見つけられないと思うので、ヒントをご用意しました。
各ヒントをクリックすると表示されます。
ぜひチャレンジしてみてください。

ヒント1

デスクトップ版しか隠してありません。スマホで探してた方、申し訳ないです。
あと、画面はフルスクリーンでやった方が良いです...!

ヒント2

規則正しくない中の規則正しい奴ら

ヒント3

"X"

Ⅵ ─ 振り返り

卒展サイトの時もそうでしたが、今回もかなり勉強になりました。
以下、教訓です。

・3D使う時は覚悟すべし
・スマートフォンの性能はポンコツと思え
・絵文字は文字参照で書け
・CSSの機能を有効活用すべし

次の学部2年生のWEB授業のTAでは(まだやると決まったわけじゃないですが)、今年度よりレベルアップしたアドバイスができそうです。

ここまで全部読んでくれた方、ほんとにありがとうございます。
意外とボリューミーになってしまいましたが、いかがでしたでしょうか。
知り合いでしたら感想いただけると嬉しいです笑

─ 染井優希