この記事は techtekt アドベントカレンダー2023 の11日目の記事です🔥
今年もさまざまな記事が投稿されていく予定ですので、興味がある方は#techtekt Advent Calendar 2023で検索してみてください!
# はじめに
こんにちは。
テクノロジー本部 エンジニアリング統括部 Miraiz開発本部でエンジニアをしている kanekoです。
# 自己紹介
役割:アプリ系 iOS Swift Android Kotlin Flutter dart Vue React / 最近はエンジニア全体の開発効率化や雑務に追われる日々
UXDigチーム としても活動中。
# この記事は何?
この記事では、抽象的なアニメーションを具体的に定義するために私がエンジニアとして七転八倒しながら具体化してきた時の話を記事にまとめたものになります。
※社内LT会で発表した内容のリライト版になります。
# 課題: デザイナーからのアニメーションの発注依頼が抽象的すぎる(時がある
異なる職能での会話は常に難しいものです。
お互いの歩み寄りが常に大事ですが、会話の進め方やお互いの職能への理解が非常に重要になってきます。
## 抽象的な会話の例
デザイナーとの会話で以下のような抽象度で会話が来る時がないでしょうか?
ーーー会話例ーーー
「あ〜なんかこう上から降ってくる感じ」
「ここのアニメーションあと1秒くらい遅くして」
「あ、なんかこうシュッて感じで」
「あ〜なんかもうちょっとシュッとして最後らへん遅く」
ーーーーーー
正直に言うと、エンジニアからすると何を言っているかさっぱりわからないときがあると思います。
少なくとも筆者はそうです。
良くてもデザイナーからの指示は「このサイトのこのアニメーションを真似して」とかになると思います。
ですが、その指示は本当にデザイナーの実現したいことをやっているといえるのでしょうか?
別のサイトの真似をするだけの実装だと、デザイナーにもエンジニアにも課題があるように感じられます。
ですが、ここで歩み寄りをしないと、課題は解決されないままです。
ユーザーにも中途半端なものを提示してしまいかねないです。
今日は上記のような抽象的な会話を、具体的な数字に落とし込めるために私がやったことを共有したいと思います。
# 課題の絞り込み
アニメーションを決定する要素は非常に多岐に渡ります。
それに対応してCSSで表現出来ることも非常に多いのですが、この記事では扱うべきではない部分も多いので、課題を絞り込みます。
## CSSで出来ること
CSSで出来ることを一旦広げてその可能性を探ってみます。
ここではCSSでの基本的なアニメーションをサンプルを通して理解することが可能です。
https://codepen.io/swan2pink/pen/ExWjgwz
また、CSSの技術の粋を集めることで、以下のような様々な表現をすることも可能です
- ゲームのストリートファイターをCSSで再現したcode
https://codepen.io/jkneb/pen/DRWdGg
- CSSデザインアワード
https://www.cssdesignawards.com/
## 波動拳うちたいですか?
上記のリンクでは非常に優れたデザインを、CSSやJavaScriptを利用して表現しています。
ですが、通常のシステム開発でそこまでのアニメーションは必要でしょうか?
必要に迫られるときもあるかもしれませんが、この記事では「Muiで表現できること」に範囲を絞ります。
※ 筆者が現在はMuiをメインで使っているのでMuiをベースに書いています
## 以下の要素は何か?
具体的にしていくために、要素を決めていきます。
アニメーションを決める要素としては、
ーーー
1. 方向(上下左右)
2. 拡大・縮小(縦横・横のみ・縦のみ・反転)
3. 回転
4. 透明度
5. スピード&イージング(開始から終了までの時間 / 速度の変化)
6. 終了時 / リピートするか
ーーー
上記のようになると思います。
デザインを決める変数という観点では、デザイントークンの考え方に近いですが、Design Tokens W3C Community Groupの引用では、アニメーションに関連した項目は無さそうだったので「デザイントークン」という言い方はここではしないようにします。
※ デザイントークンって何?と言う方にはこちらの記事がオススメです。
以下のように扱う対象を絞ります
ーーー
1. 方向(上下左右) | Muiに任せる ☑︎
2. 拡大・縮小(縦横・横のみ・縦のみ・反転) | Muiに任せる ☑️
3. 回転 | 今回の守備範囲外(やりたい場合はCSSで)🙅♀️
4. 透明度 | Muiに任せる ☑️
5. スピード&イージング(開始から終了までの時間 / 速度の変化) | ここをやる✅
6. 終了時 / リピートするか | 今回の守備範囲外(やりたい場合はCSSかGifにすることなどを検討)🙅♀️
ーーー
# それぞれの要素を分解する
## Muiのアニメーション(Transition)の理解
https://mui.com/material-ui/transitions/
Collapse, Slide, Fade, Grow, Zoom
などの種類が用意されているので、サンプルを用意したりするのが容易です。CSSを1から実装したりする手間も省けます。
上記のサイトで実際にサンプルを触ることが可能なので、イメージを掴むために触ってみて理解を深めてください。
※ 基本的に文字と筆者の説明だけで理解するのは難しいです
### 方向(上下左右)
方向のパラメーターをもっているコンポーネントはMuiではCollapseとSlideの二つ。
オブジェクト自身の変更とオブジェクトの座標の変換に分けられる。
- Collapseは、vertical,horizonalの上下2種類がある。
こちらはオブジェクト自身の変更となる。オブジェクトの表示部分と非表示部分をアニメーションで変化させることが可能。
- Slideは、up,down,left,rightの上下左右の4種類がある。
オブジェクトの座標を変更させることが可能。
### 透明度
- Fadeは、オブジェクト全体の透明度を変更させます。
### 拡大・縮小(縦横・横のみ・縦のみ・反転)
- Zoomはオブジェクトのの中心から外側に展開します。
- Growはオブジェクトの中心から外側に拡大し、同時に透明から不透明にフェードインします(ZoomとFadeの合わせ技のような理解)
## スピード&イージング
全てのアニメーションで必要になるのが「スピード」と「イージング」になります。
## Webアニメーションの世界におけるスピードとは何か
エンジニアが扱うソースコード内で「スピード」を直接決めることはありません。
「速度(速さ)= 距離 ÷ 時間 」の公式がここでも役に立つのですが、距離と時間を決めることでアニメーションの「速度」を逆説的に決める形になります。
### 距離について
方向の部分でも挙げましたが、移動するアニメーションでは基本的に「オブジェクト自身の変更」or 「オブジェクトの座標の変更」の2種類にわけられます。
Collapseのようなオブジェクト自身の変更の場合は、アニメーションが開始する場所と終了する場所はオブジェクトの大きさに関連します。
Slideのような、オブジェクトの座標の変更の場合は、A地点からB地点といったような変更に限られます。
なので、オブジェクトのサイズやアニメーションの種類が決まった時に、基本的に「距離」は既に確定しています。
### 時間はこちらで決定する必要がある
なので、開始から終了までの「時間」を設定してあげれることで速度が逆説的に決定するし、プログラムの内部もそのように組まれています。
補足:現実の世界と違って、Webの世界ではオブジェクトの「重さ」や「重力」などは存在しないので考慮する必要がありません。
## easingとは何か
こちらのサイトの説明がわかりやすいです。easings.net
現実の物体は、即座に動いたり停止したりすることはなく、一定の速度で動くこともほとんどありません。引き出しを開けるとき、私たちは最初に引き出しをすばやく引き出し、それが外に出てくるにつれてゆっくりと動かします。床に向けてなにかを(例えばペンのような)放すと、最初に重力によって下に向かって加速し、床に当たった後上に跳ね返ります。
また、上記のサイトではおおよそどのような種類のeasingがあるかを知ることが可能です。
## 実際どのように設定するの?
上記のサイトのそれぞれのeasingの詳細を開くと、ソースコードが見れますが、以下のようになっているのが見れるかと思います。
```
cubic-bezier(0.33, 1, 0.68, 1)
```
これだけだと、なんのことか非常に変わりづらいと思います。
そこで、以下のサイトが理解に役立ちます。
このサイトでは、3次ベジェ曲線を用いてeasingを自分で設定してアニメーションに反映させて動きを見ることが可能です。
## cubic-bezierを理解する
上記のサイトのグラフを数分間でも触っていれば、なんとなく理解できてくるかと思います。
筆者の稚拙な説明よりも、触っていただいた方が確実に理解は深まると思います。
なので、上記のサイトグラフを触ってもらっている前提で補足を加える形としたいと思います。
## cubic-bezierとは
cubic-bezierとはピエール・ベジェさんが考案した曲線の書き方です。
Cubic = 立方体 => 3次元 の意味で bezierは人の名前になります。
## 4つの引数は何を決定しているか
サイト上では丁寧に色分けされています。
画面左側の赤い球と画面右側の緑の球がそれぞれあります。
引数の1つ目と2つ目が赤い球のx軸とy軸
引数の3つ目と4つ目が緑の球のx軸とy軸
を決定しています。
それぞれが、2つの点の座標を決定していることがグラフを操作してもわかるかと思います。
これにより、easingを決定することが可能です。
## 実物があると良いよね!
【いろいろと書きましたが実物でどんな感じか掴みたいですよね】
社内向けで以下のようなStorybookを作りました!
## 最初の会話に立ち返ってみる
これまでの記事を理解した上で、最初の会話に戻ってみましょう。
ーーー会話例ーーー
「あ〜なんかこう上から降ってくる感じ」
「ここのアニメーションあと1秒くらい遅くして」
「あ、なんかこうシュッて感じで」
「あ〜なんかもうちょっとシュッとして最後らへん遅く」
ーーーーーー
この会話が以下のように解釈出来るようになったかと思います🎉
ーーーーーー
「あ〜なんかこう上から降ってくる感じ」(アニメーションの種類と方向の話。この場合は、Slideコンポーネントでdirectionはdown)
「あと1秒くらい遅くして」(アニメーションの時間の話: timeを1000上げる)
「あ、なんかこうシュッて感じで」(easingの最初は等速で早めに動かす)
「あ〜なんかもうちょっと最後らへん遅く」(easingの最後はディレイさせる)
ーーーーーー
# 振り返り:アニメーションの定義が難しいのは何故?
## さまざまな軸や要素が複雑に絡んでいる
これまで整理してきた通りですが、アニメーションはさまざまな要素が絡んでいます。
エンジニアの言葉では「変数」が多いと言えるかもしれません。
改めて整理すると
- 時間軸 / 進行率 (これだけで3次元)
- アニメーションの種類 / 方向 / 適用範囲
- 回転 / 色 / etc.. (今回は扱わなかった範囲)
になります。
これらを統合して最終的にアニメーションとして出力されることになると考えると、ものが動くことを伝えるのは非常に難しいことに見えるかと思います。
説明が抽象的にもなることが見て取れるかと思います。
## さらにやりたい事(ネクストアクション)
上記でデザイナーとエンジニアがアニメーションについてコミュニケーションを取る上で、一定のベースが出来たかと思います。
更に企画面での影響を考えていきたいと思います。
## 各項目が与える効果・印象
サービス全体のデザインやUI/UXを考えていく上で、色彩は非常に重要なテーマです。ある程度サービスのUI/UXを考えていくと「プライマリーカラー」を設定する必要があると思います。
色彩心理学と言う分野もあるそうですが、色にはさまざまな効果がありブランディングなどにも影響を与えます。
その他、TypoGraphy,Font,Radius etc...
サイトの印象はさまざまな要素で成り立っていると言えるかと思います。
では、アニメーションはどうでしょうか?
今までまとめてきた範囲での要素に対して、疑問を列挙してみたいと思います。
ーーー
・アニメーションの種類
ex: Zoom と Grow ではどのような印象の変化があるか。
・direction / orientation(方向 / あれば)
Slideコンポーネントで左から来る場合と、右から来る場合ではどのような違いがあるか。
・timeout (transitionの時間 / 速度に関連する)
速度の違いによる印象はどうか?
アニメーションは最短何秒まで認識されるか。遅い場合は何秒まで許されるか。
・easing(開始から終了まで速度の変化)
それぞれのeasingでは、どのような印象の違いがあるか。
timeとの関連はどうなるか。
ーーー
上記を踏まえて、企画の要求に合致したアニメーションを設定するには、どうすれば良いでしょうか?
「アニメーションが与える印象」について検索すると、論文多く展開されており、今もなお研究されている分野のようです。
興味は尽きませんが、今後の研究に期待したいところです。
以上で終わりになります!
それでは、良いお年を🎄
金子 広大 Kodai Kaneko
エンジニアリング統括部 Miraiz開発部 MIRAIZ開発グループ リードエンジニア
iPhoneとAndroidのネィティブアプリで、 アプリの企画 -> デザイン -> 開発 -> リリース -> グロースまでの経験を生かして、活動中。現在、React Next TypeScriptにも挑戦中。
※2023年12月現在の情報です。