Reactで始めるjs + cssアニメーション概論
はじめに
SHIFTBRAIN さんがデザインされるページってめっちゃいいですよね(まわしものではない)
BtoB の 01 フェーズでプロダクトの管理画面にこんな神のようなクオリティを求められることはないことの方が多いですが、せっかく UI 作るのに携わっているならアニメーションの一つや二つ実装したいですよね
今回、開発中のプロダクトにいくつかアニメーション(簡単なやつだよ、SHIFTBRAIN さんのような神 UI ではないよ)を入れる機会があったので、その時の学びをカンタンなアニメーション概論として記事にしようというお話
React でのアニメーションの第一歩を踏む出すきっかけになれば!
記事のターゲット
- React でのアニメーションの第一歩を踏み出したい人
- 小手先のテクニックで表現力に差をつけたいそこのあなた
環境
実際のコード
(筆者が tailwindcss を患っているため tailwindcss が使われています)
作ったもの(カクカクしてるのは gif だからです。実物はもっとスマートに動いてます maybe)
transition + js を使ったアニメーション
transition
プロパティが指定された css の class を className に持つ要素に対して、hover
や onClick
などのイベントをトリガに transition
で指定したスタイルを変更した class をその要素に付与することでアニメーションさせる方法です
下記の実装例を見てもらえればわかるんですが、シンプルな動きをさせるぶんには結構簡単
css 側でtransition: height 0.2s;
でアニメーションつけたいプロパティを指定して、onClick
時に className に class 変化させる height を持った class を入れてる
classnames(styles["content1"], {
[styles.high]: high,
});
実装例
/* postcssの`postcss-nested`使ってscssのようにネストして書けるようにしてやす */
.content1 {
transition: height 0.2s;
height: 40px;
&.high {
height: 300px;
}
}
export const Example = (): JSX.Element => {
const [high, setHigh] = useState<boolean>(false);
return (
<div>
<div className="mb-6">
<Button
color="primary"
label="click me!"
labelSize="sm"
onClick={() => setHigh(!high)}
rounded
/>
</div>
<div
className={classnames(styles["content1"], {
[styles.high]: high,
})}
>
<Text color="white">content1</Text>
</div>
</div>
);
};
@keyframes + animation プロパティ を使ったアニメーション
transition + js を使ったアニメーションで width やら height やら色変えたりなど(もしくはそれらを組み合わせる)の簡単なアニメーションはできるんですが、この要素を下に動かした後に回転してそこから右に動かしたりもできますよね?
とか言われると詰みます
そんなときは@keyframes
とanimation プロパティ
を使いましょう
css の@keyframes
で要素の0 から 100 の状態を定義します
0 から 100 の状態とは簡単にいうと要素が 0 秒だったら height が 0 で 1 秒だったら・・(以下繰り返し)、最後に 5 秒の時は height を 100px にしようみたいな状態のことです
@keyframes
で定義した要素の 0 から 100 の状態をanimation プロパティ
で使います
/* 0の位置からy軸に200px動くことが書かれてる */
@keyframes moveDown {
from {
transform: translateY(0);
}
to {
transform: translateY(200px);
}
}
.content3 {
animation-name: moveDown; /* moveDownって名前のkeyframes使うよ */
animation-duration: 1s; /* 0から100にいくまでの時間は1秒だよ */
animation-timing-function: ease-in; /* 0から100までどんな感じに動かしたいんだい */
animation-iteration-count: infinite; /* アニメーションは繰り返すのかい */
animation-fill-mode: forwards; /* アニメーションが始まる前と終わった後の状態はどうすんだい */
}
こいつが該当します
@keyframes
の指定は from to だけでなくパーセント指定もできます
/* アニメーションが0%の時は角度が0度で10%の時は角度が10度で・・・以下略 */
@keyframes swing {
0% {
transform: rotate(0deg);
}
10% {
transform: rotate(10deg);
}
30% {
transform: rotate(0deg);
}
40% {
transform: rotate(-10deg);
}
50% {
transform: rotate(0deg);
}
60% {
transform: rotate(5deg);
}
70% {
transform: rotate(0deg);
}
80% {
transform: rotate(-5deg);
}
100% {
transform: rotate(0deg);
}
}
.content5 {
animation-name: swing;
animation-duration: 0.5s;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-direction: alternate; /* アニメーションはどの方向で再生するんだい */
}
こいつが該当します
最後に
translate
には 2 次元だけでなく 3 次元(translate3d
やtranslateY
)の指定もでき・・・
そう、もうお気づきかもしれませんが、ここまで読んだあなたは CSS アニメーションの深淵の入り口に立っています
Let's enjoy css animation!!
少し昔に作った作品を添えて
Discussion