React Simple Animateでアニメーション処理
Reactコンポーネントをアニメーションさせるというのは若干面倒な点もあるのですが、React Simple Animateは名前の通り超簡単にアニメーションを実現させてくれるライブラリです。
提供されているコンポーネントは、Animate
, AnimateKeyframes
, AnimateGroup
の3つ。これらの使い方は、公式のサンプルを眺めれば瞬時に理解できるほどシンプルです。
ただし、v2とv3でprops名が異なることがあるため注意が必要です。この記事ではv3.3.0を対象にしています。
Animate
Animate
はスタイルをA⇔Bでアニメーションさせます。最低限必要なpropsは下記の3つです。
<Animate
play={false}
start={{ opacity: 1, filter: 'blur(0)' }}
end={{ opacity: 0, filter: 'blur(10px)' }}
>
<MyComponent />
</Animate>
start
が初期スタイル、end
が変更後のスタイルです。play
がtrue
になったときにアニメーションしますが、最初からtrue
だとコンポーネントロード後にアニメーションします。
その他の主なオプションは以下です。
- duration - アニメーションの長さ
- deplay - アニメーション開始までの時間指定
- complete - アニメーション完了後のスタイル指定
- easeType - Easingタイプの指定
- onComplete - アニメーション完了後のコールバック
例:文字のフェードアニメーション(抜粋)
import React from 'react';
import { Animate } from 'react-simple-animate';
const MyComponent = ({ play }) => (
<>
<Animate
play={play}
start={{ opacity:1, filter: 'blur(0)' }}
end={{ opacity: 0, filter: 'blur(10px)' }}
>
<p>Hello World!</p>
</Animate>
</>
);
export default MyComponent;
単にテキストをフェードイン/フェードアウトさせています。play
は親コンポーネントからtrue/false
を渡して、スイッチさせているだけです。
AnimationKeyframes
AnimationKeyframes
は、CSSキーフレームアニメーションそのものです。
必須propsはplay
とkeyframes
です。
<AnimateKeyframes
play={true}
pause={false}
iterationCount="infinite"
direction="alternate"
duration={5}
keyframes={[
'transform: rotateX(0) rotateY(0) rotateZ(0)',
'transform: rotateX(360deg) rotateY(360deg) rotateZ(360deg)',
]}
>
<MyComponents />
</AnimateKeyframes>
keyframes
はデフォルトでは等間隔にアニメーションを行います。上記は下記と同等です。パーセント(中割り)は自由に指定可能で、2つに限る必要はありません。
keyframes={[
// 0%
{ 0: 'transform: rotateX(0) rotateY(0) rotateZ(0)' },
// 100%
{ 100: 'transform: rotateX(360deg) rotateY(360deg) rotateZ(360deg)' }
]}
残りのオプションは以下です。
- pause - アニメーションの一時停止オプション(trueで一時停止)
- iterationCount - 繰り返し回数
- direction - アニメーション再生の向き(animation-directionに該当)
- duration - アニメーションする秒数
- easeType - Easingタイプの指定
- fillMode - 実行前後にどうスタイルを適用させるか(animation-fill-modeに該当)
例は、スターウォーズのOPをAnimationKeyframes
で部分再現したものです👉プレビュー
例:AnimateKeyframesの抜粋(全文)
import React from 'react';
import { AnimateKeyframes } from 'react-simple-animate';
const MyComponent = () => (
<div className="starwars-demo">
<AnimateKeyframes
play={true}
iterationCount="infinite"
direction="normal"
duration="5"
easeType="ease-out"
keyframes={[
{ 0: "opacity: 0; transform: scale(1.5) translateY(-0.75em)" },
{ 20: "opacity: 1" },
{ 89: "opacity: 1; transform: scale(1)" },
{ 100: "opacity: 0; transform: translateZ(-1000em)" }
]}
>
<img src="//cssanimation.rocks/demo/starwars/images/star.svg" />
</AnimateKeyframes>
<AnimateKeyframes
play={true}
iterationCount="infinite"
direction="normal"
duration="5"
easeType="ease-out"
keyframes={[
{ 0: "opacity: 0; transform: scale(1.5) translateY(0.5em)" },
{ 20: "opacity: 1" },
{ 90: "opacity: 1; transform: scale(1)" },
{ 100: "opacity: 0; transform: translateZ(-1000em)" }
]}
>
<img src="//cssanimation.rocks/demo/starwars/images/wars.svg" />
</AnimateKeyframes>
</div>
);
export default MyComponent;
keyframs内では、transform
でスケールとtransformZ
でZ軸への移動をしています。遠近感のトリックはCSSです。
.starwars-demo {
transform-style: preserve3d;
perspective: 800px;
}
利用しているのは、transform-styleとperspectiveです。前者で要素を3D空間に配置し、後者でそのZ軸(奥行き)の距離を設定しています。
AnimationGroup(Animation Sequences)
AnimationGroup
は順番通りの(シーケンス)アニメーションを実現します。複数の要素を規定の順番でアニメーションさせたい場合は、これを利用します。
<AnimateGroup play={true}>
<Animate start={{ opacity: 0 }} end={{ opacity: 1 }} sequenceIndex={0}>
first
</Animate>
<Animate start={{ opacity: 0 }} end={{ opacity: 1 }} sequenceIndex={1}>
second
</Animate>
<Animate start={{ opacity: 0 }} end={{ opacity: 1 }} sequenceIndex={2}>
third
</Animate>
</AnimateGroup>
Animate
をAnimateGroup
でラップすることで、順番にアニメーションさせられます。順番はsequenceIndex
に指定した順です。sequenceId
とsequences
で同様のことも行えるようですが、こちらは公式ドキュメントに沿うと自分の環境では動作しなかったため、様子見です。
<AnimateGroup play sequences={[
{ sequenceId: 'first', ...props},
{ sequenceId: 'second', ...props },
{ sequenceId: 'third', ...props }
]}>
<Animate sequenceId="first">first</Animate>
<Animate sequenceId="second">second</Animate>
<Animate sequenceId="third">third</Animate>
</AnimateGroup>
基本はAnimate
コンポーネントのため、特に難しいことはないはずです。
尚、ここまでの例はすべてインラインスタイルで定義してきましたが、公式にあるようにHookでの記述も可能です(React@^16.7以上が必要)。