出現・消滅アニメーション
Animated.Viewのentering/exitingプロパティとFadeInなどのプリセットを使い、要素がツリーに追加・削除されるときのアニメーションを組み立てます。プリセットの種類とビルダーAPIのモディファイアも扱います。
第3部までのアニメーションは、すでに画面にある要素のスタイルを動かすものでした。第4部で扱うのは、要素が画面に現れる瞬間と消える瞬間のアニメーションです。
リストに項目が追加されたときにふわっとフェードインさせる、削除された項目を横に滑らせて消す。こうした動きは、これまでのように共有値とスタイルを自分で組み立てなくても、Reanimatedがあらかじめ用意したプリセットを渡すだけで実現できます。
enteringとexiting
出現・消滅アニメーションは、Animated.Viewのenteringとexitingプロパティにアニメーションを渡すだけで動きます。要素がReactのツリーに追加されたときにenteringが、ツリーから削除されるときにexitingが再生されます。
import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
function App() {
return <Animated.View entering={FadeIn} exiting={FadeOut} />;
}
再生のきっかけは、要素がマウント・アンマウントされることです。つまり、条件付きレンダリングやリストの増減にそのまま反応します。次のように状態で表示を切り替えれば、表示時にentering、非表示時にexitingが走ります。
function App() {
const [shown, setShown] = useState(true);
return (
<>
{shown && <Animated.View entering={FadeIn} exiting={FadeOut} />}
<Button title="切り替え" onPress={() => setShown((v) => !v)} />
</>
);
}
下のデモでプリセットを選び、ボタンで要素を出し入れしてみてください。選んだプリセットに応じて、出現と消滅の動きが変わります。
プリセットの種類
Reanimatedには、方向やスタイルの異なる多くのプリセットが用意されています。名前は「効果 + 方向」の組み合わせでできていて、Inが出現用、Outが消滅用です。たとえばFadeInLeftは左からフェードしながら現れ、SlideOutRightは右へ滑って消えます。
主な効果は次のとおりです。
Fade— 透明度を変化させるフェード。FadeIn/FadeInUp/FadeInDown/FadeInLeft/FadeInRightなどBounce— 弾むように現れる。BounceInとその方向つきバリエーションFlip— 軸まわりの回転でめくる。FlipInEasyX/FlipInYLeftなどLightSpeed— 傾きと透明度を伴って横方向に走る。LightSpeedInRightなどPinwheel— 回転・スケール・透明度を組み合わせた風車のような動きRoll— 回転しながら横に転がる。RollInLeft/RollInRightRotate— 角を軸に回転しながら現れる。RotateInDownLeftなどSlide— 画面外から滑り込む。SlideInLeft/SlideInUpなどStretch— X軸またはY軸方向に伸縮する。StretchInX/StretchInYZoom— スケールで拡大縮小する。ZoomInとその方向つきバリエーション
それぞれに対応するOut系のプリセットがあり、消滅アニメーションとして使えます。全プリセットの一覧と、各プリセットが内部で使う初期値・目標値は、公式ドキュメントの出現・消滅アニメーションにまとまっています。
モディファイアで調整する
プリセットはそのまま渡すだけでも動きますが、ビルダーのモディファイアをチェーンして細かく調整できます。第2部で見たwithTimingやwithSpringのモディファイアと考え方は同じです。
時間ベースの調整
再生時間とイージングは、.duration()と.easing()で指定します。
FadeOutLeft.duration(500).easing(Easing.ease);
.easing()の既定はEasing.inOut(Easing.quad)です。イージング関数の中身は第2部のwithTimingの章で扱ったものと同じなので、そのまま使えます。
バネベースの調整
.springify()を挟むと、時間ベースの代わりにバネの物理でアニメーションします。バネの硬さや重さは、withSpringと同じモディファイアで調整します。
FadeInUp.springify()
.damping(30)
.mass(5)
.stiffness(10)
.overshootClamping(false);
.springify()を使うと.duration()や.easing()は効かなくなります。時間ベースとバネベースは排他だと考えてください。
共通のモディファイア
効果の種類を問わず使えるモディファイアもあります。
FadeInDown.delay(500)
.randomDelay()
.reduceMotion(ReduceMotion.Never)
.withInitialValues({ translateY: 420 })
.withCallback((finished) => {
console.log(`中断なく終了: ${finished}`);
});
.delay(ms)— 再生を始めるまでの遅延.randomDelay()— 遅延を0から指定値の間でランダムにする。指定がなければ1000msを上限にする.reduceMotion(ReduceMotion)— 端末の「視差効果を減らす」設定への反応を決める.withInitialValues(values)— アニメーションの初期値を上書きする。プリセットが動かすプロパティだけを受け付ける.withTargetValues(values)— アニメーションの目標値(アニメーション後に到達する状態)を上書きする。プリセットが動かすプロパティだけを受け付ける.withCallback(finished => {})— アニメーション終了時に呼ばれる。中断なく終わればfinishedがtrueになる
.withInitialValues()で受け付けられるプロパティはプリセットごとに決まっています。たとえばFadeInDownならopacityとtranslateYだけです。どのプリセットが何を動かすかは、公式ドキュメントの各プリセットの型定義で確認できます。
使うときの注意点
いくつか、公式が挙げている注意点があります。
パフォーマンスのため、アニメーションのビルダーはコンポーネントの外か、useMemoの中で組み立てることが推奨されています。レンダーのたびにモディファイアをチェーンして新しいビルダーを作ると無駄が出ます。
New Architectureでは、出現アニメーションの設定に内部的にnativeIDが使われます。これを上書きすると出現アニメーションが動かなくなるので注意してください。TouchableWithoutFeedbackのように子要素のnativeIDを書き換えるコンポーネントがある場合は、アニメーションさせたい子をViewで包むと回避できます。
また、アニメーションを持たないビューを削除すると、その子要素の消滅アニメーションは走りますが、親のビューは子のアニメーション完了を待たずに消えます。これはビューのフラット化によるもので、親にcollapsable={false}を付けると避けられます。
プリセットはあくまで出発点です。より複雑な動きが必要になったら、次章以降で扱うキーフレームやカスタムアニメーションに進めます。まずはプリセットで十分に表現できる範囲を押さえておくのがよいでしょう。