Animated APIは、JavaScriptスレッドに負荷をかけることなく60 FPSのアニメーションを提供する、React Native組込みの宣言的アニメーションライブラリです。React Native 0.76 (2025) の公式ドキュメントによると、Animated APIはすべてのタイプのアニメーションでuseNativeDriverをサポートし、UI Managerを通じて計算をネイティブスレッドに移します。このライブラリは、複雑なアニメーションチェーン、インタラクティブなジェスチャー、そして不透明度から変換までのあらゆるスタイルプロパティの内挿を作成できます。
メインポイント
Animated APIは、モバイルアプリで滑らかで高性能なアニメーションを作成するために設計された、React Nativeのコアに組み込まれた宣言的アニメーションライブラリです。Web開発でのCSSアニメーションとは異なり、Animated APIはJavaScriptブリッジやネイティブドライバーを通じて直接ネイティブUIスレッドと動作します。このライブラリは、数値を保持し、すべての依存コンポーネントを自動的に変化にサブスクライブするコンテナAnimated.Valueの構想を中心に構築されています。Animated.timingまたはAnimated.springで値が変わると、ライブラリはReactコンポーネントを再レンダリングせずに中間状態を計算します。これは60 FPSを維持するのに重要です。Animated APIは、transform、opacity、width、height、top、left、backgroundColorなど、すべてのスタイルプロパティをサポートします。React Nativeのドキュメントは、高いパフォーマンスと両プラットフォームでの予測可能な動作が必要なすべてのアニメーションシナリオでAnimated APIを推奨しています。
Animated APIの基礎はAnimated.Valueです。コンストラクタnew Animated.Value(0)で初期化される数値コンテナです。各Animated.Valueは初期値を保持し、アニメートメソッドを提供します: timing、spring、decay。timingメソッドは、持続時間、遅延、easingパラメータを使って線形またはeasingアニメーションを作成します。springメソッドは、摩擦、張力、速度のパラメータを使って物理的なバネアニメーションを実装します。decayメソッドは、惯性と衰減を伴うアニメーションを作成します — スワイプやスクロールに便利です。すべてのメソッドはAnimated.Compositeオブジェクトを返し、start()で開始し、stop()で停止できます。アニメーションは独立したスレッドで実行されます: useNativeDriver = trueの場合、計算はネイティブUIスレッドで行われ、JavaScriptスレッドはイベント処理とロジックのために自由です。
Animated.timingは、制御された持続時間を持つ基本アニメーションメソッドです。構成を受け付けます: toValue、duration (デフォルト500ms)、easing (デフォルトでEasing.linear)、delay。EasingモジュールのEasing関数は非線形の加速を可能にします: Easing.bezier、Easing.elastic、Easing.bounce。一定速度のアニメーションにはEasing.linearを使い、自然な加速にはEasing.inOutを使います。重要: Animated.timingは、デバイスの負荷に関わらず、指定された時間内にtoValueでアニメーションが精確に終了することを保証します。
Animated.springは、フックの法則に基づいたバネアニメーションモデルを実装します。friction (摩擦)パラメータは振動回数を制御します: 摩擦が高いほど停止が速くなります。tension (張力)パラメータはバネの剛性を決定します: 高い張力は動きを加速します。velocity (速度)パラメータは惯性を伴うアニメーションの初期速度を設定します — ユーザージェスチャーに従うアニメーションに重要です。Animated.springに固定持続時間はありません — 速度と振幅がしきい値に達するとアニメーションが完了します。
Animated APIは、4つの組込みアニメーテッドコンポーネントを提供します: Animated.View、Animated.Text、Animated.ScrollView、Animated.Image。各、対応するネイティブコンポーネントのラッパーで、スタイルプロパティにAnimated.Valueを渡すことができます。Animated.Viewは最もよく使われるコンポーネントで、通常のViewと同じpropsを受け付けますが、styleにアニメートされた値をサポートします。Animated.Textは、テキストの色や文字間スペーシングをアニメートするのに便利です。Animated.ScrollViewは、scrollToやcontentOffsetをアニメートできます。Animated.Imageは、画像読み込み中にアニメートされた不透明度とスケールをサポートします。別のコンポーネントをアニメートする必要があれば、Animated.createAnimatedComponent(MyComponent)を使います。
import React from 'react';
import { Animated, View, Button } from 'react-native';
const FadeInView = () => {
const opacity = useRef(new Animated.Value(0)).current;
const fadeIn = () => {
Animated.timing(opacity, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}).start();
};
return (
View
Animated.View { style: [{ opacity }] }
Button title="Fade In" onPress={fadeIn}
);
};
内挿は、Animated.Valueの入力数値範囲を別のタイプの出力値に変換するメカニズムです。interpolateメソッドは、inputRange (入力値の配列)とoutputRange (出力値の配列)をもつ構成を受け付けます。outputRangeのタイプ: 数値 (座標、不透明度)、文字列 ('deg'を使った回転角)、十六進数色 ('#ff0000')、変揻オブジェクト。内挿は、easingとextrapolate (指定範囲外の動作: clamp、extend、identity)をサポートします。例えば、ドラッグジェスチャーで、指の位置0から200を不透明度1から0に変換し、スワイプ時にフェード効果を作れます。内挿システムは複雑な多歩驿アニメーションを作成できます: 値0-0.5-1.0を黄色-オレンジ-赤色に変換できます。
const spinValue = new Animated.Value(0);
Animated.timing(spinValue, {
toValue: 1,
duration: 3000,
easing: Easing.linear,
useNativeDriver: true,
}).start();
const spin = spinValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg'],
});
Animated APIは3つのアニメーションコンポジションモードをサポートしています: Animated.sequence、Animated.parallel、Animated.stagger。Animated.sequenceはアニメーションを次々に実行します: 前のアニメーションが終了したら次が始まります。Animated.parallelは、共通の終了コールバックを使ってすべてのアニメーションを同時に実行します。Animated.staggerは、各開始の間に遅延を設けてアニメーションを実行します — 波のような効果を作るのに便利です。コンポジションはネスト可能です: 並列グループの順次または順次の並列。これにより、複雑なチェーンを作成できます: 遅延ありの要素表示アニメーション、fade-in付き並列slide-in、その後でbounceとshakeの順次。
Animated.sequence([
Animated.timing(fadeAnim, {
toValue: 1,
duration: 500,
useNativeDriver: true,
}),
Animated.parallel([
Animated.timing(scaleAnim, {
toValue: 1.1,
duration: 200,
useNativeDriver: true,
}),
Animated.spring(colorAnim, {
toValue: 1,
friction: 4,
useNativeDriver: true,
}),
]),
]).start();
useNativeDriverは、アニメーションロジックをJavaScriptスレッドからネイティブUIスレッドに移すアニメーション構成オプションです。useNativeDriverがない場合、アニメーションはJavaScriptブリッジを通じて実行されます: 値が変わるたびにネイティブスレッドに送信され、JSスレッドが非同期処理で忙しいときに遅延が生じます。useNativeDriver = trueの場合、Animated.Valueはネイティブ側で直接更新され、JavaScriptスレッドはイベント処理、APIリクエスト、React再構築のために自由になります。制限: useNativeDriverはレイアウト以外のプロパティだけをサポートします — opacity、transform、backgroundColor (PlatformColor経由)。レイアウトプロパティ (width、height、top、left) には、NativeAnimatedModuleまたはLayoutAnimationが必要です。React Native 0.76によると、レイアウトベースのものを除き、すべてのアニメートプロパティがネイティブドライバーを通じてサポートされます。useNativeDriverモードは、可能な場合はすべてのアニメーションで推奨されます — FPSが30-40から安定で60に向上します。
PanResponderは、Animated APIと良く統合するネイティブのReact Nativeジェスチャー処理システムです。PanResponderは、指の位置に基づいてAnimated.Valueを更新できるコールバックonPanResponderMoveとonPanResponderReleaseを提供します。より複雑なジェスチャー (スワイプ、ピンチ、回転) には、react-native-gesture-handlerライブラリを使います。これはアニメーションと同期して動作し、多指のジェスチャーでゅ60 FPSを提供します。Gesture Handlerは、マニュアルコールバック処理なしにジェスチャーをAnimated.Valueに直接結合するメソッドAnimated.eventを提供します。Gesture Handler + Animated APIの組み合わせは、React Nativeアプリのインタラクティブアニメーションの業界標準です。
Animated.eventは、ネイティブイベント (例: gestureEvent) を直接Animated.Valueに結合するメソッドです。コールバックでのマニュアル処理とは異なり、Animated.eventはネイティブスレッドでシンクロナスに動作し、フレームごとにJavaScriptブリッジが必要ありません。これにより、高速なスワイプ中でも滑らかなアニメーションが得られます。Animated.eventはマッピングの配列を受け付け、各要素がイベントフィールドをAnimated.Valueに結合します。ネストアクセスもサポートされます: Animated.event([{ nativeEvent: { translationX: xValue } }]).
React NativeプロジェクトでのAnimated APIの使用例を3つ紹介します。例1: opacity + translateYの順次でカード表示アニメーション。例2: springを使ったボタンのパルスアニメーション。例3: PanResponderを使ったインタラクティブドラッグ要素。すべての例でuseNativeDriver = trueを使用し、React Native 0.76の最良実践に従っています。
const CardWithAnimation = () => {
const anim = useRef(new Animated.Value(0)).current;
React.useEffect(() => {
Animated.spring(anim, {
toValue: 1,
friction: 6,
tension: 40,
useNativeDriver: true,
}).start();
}, []);
const translateY = anim.interpolate({
inputRange: [0, 1],
outputRange: [50, 0],
});
return (
Animated.View {
style: [{ opacity: anim, transform: [{ translateY }] }]
}
);
};
Springアニメーションは、物理バネモデルにより自然なパルス効果を作り出します。低摩擦 (2-4) と高張力 (100-150) の設定で、自然に衰減する柔らかな振動が得られます。無限パルスには、順次サイクル (scale → 1.2, scale → 1.0) でAnimated.loopを使います。パルスは、ローディングインジケーター、通知、アクセントボタンに使用されます。
よくある質問
Animated APIはアニメーションを完全に制御できます — 持続時間、easing、内挿、コンポジション。LayoutAnimationは、自動内挿でレイアウト変化をアニメートする組込みのReact Nativeシステムです。Animated APIはAnimated.Valueと構成の明示的宣言が必要ですが、複雑なチェーンを作成できます。LayoutAnimationはステート変更で自動的に発火し、より簡単に使えますが、柔軟性に制限があります。
はい、widthやheightはAnimated APIでアニメートできますが、useNativeDriverはサポートしません。レイアウトプロパティのアニメーションにはJavaScriptドライバーが必要です。width/heightにはAnimated.ValueをtoValueと使い、useNativeDriverをfalseに設定します。レイアウトアニメーションの性能向上には、LayoutAnimationまたはreact-native-reanimatedを検討してください。
Animated.timingまたはAnimated.springが返したアニメーションオブジェクトのstop()メソッドを呼びます。例: animRef.stop()。アニメーションがsequenceまたはparallelの一部の場合、stop()はグループ全体を停止します。ステータスを確認するには、start(callback)のコールバックを使います — 強制停止時にはfinished: falseをもつresultオブジェクトが伝達されます。
Animated.ValueXYは、2次元座標のコンテナで、xとyの2つのAnimated.Valueを保持します。画面上の要素位置をアニメートするのに使います (drag、pan、swipe)。ValueXYは、スタイル用の便利なgetLayout()と変揻用のgetTranslateTransform()メソッドを提供します。両軸を同時にアニメートする必要があるPanResponderで使用するのに便利です。
開発メニュー (Cmd+D / Cmd+M) に組み込まれたReact Nativeパフォーマンスモニターを使います。FPSモニターを有効にすると、リアルタイムでUI FPSとJS FPSが表示されます。プログラム的な測定には、import { InteractionManager }を使ってアニメーションの完了をトラックします。安定した60 UI FPSと50+ JS FPSが、良く最適化されたアニメーションの目安です。UI FPSが30を下回った場合は、useNativeDriverを無効にするか、同時実行中のアニメーション数を最適化します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。