RORK LABEN
PRODUCT — Rork Maxがネイティブ Swift アプリを生成。iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageに対応しますNATIVE — Rork MaxはAR/LiDAR・Metalの3Dゲーム・Dynamic Island・Live Activities・HealthKit・Core MLなどを解放しますCLASSIC — 通常のRorkはReact Native(Expo)で、英語の説明だけからiOS/Androidアプリを生成しストア配信できますFUNDING — a16zから$2.8Mを調達(別途$15Mも)。月743,000訪問・成長率85%と伸びていますPRICING — 無料で始められ、有料プランは月25ドル〜。Rork Maxは月200ドルですCHOICE — クロスプラットフォームのRorkか、Apple専用機能まで踏み込むRork Maxか、用途で選び分けられますPRODUCT — Rork Maxがネイティブ Swift アプリを生成。iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageに対応しますNATIVE — Rork MaxはAR/LiDAR・Metalの3Dゲーム・Dynamic Island・Live Activities・HealthKit・Core MLなどを解放しますCLASSIC — 通常のRorkはReact Native(Expo)で、英語の説明だけからiOS/Androidアプリを生成しストア配信できますFUNDING — a16zから$2.8Mを調達(別途$15Mも)。月743,000訪問・成長率85%と伸びていますPRICING — 無料で始められ、有料プランは月25ドル〜。Rork Maxは月200ドルですCHOICE — クロスプラットフォームのRorkか、Apple専用機能まで踏み込むRork Maxか、用途で選び分けられます
記事一覧/開発ツール
開発ツール/2026-06-23中級

「視差効果を減らす」をオンにした人に、アニメーションをどう返すか — Expo で Reduce Motion を尊重する層を作る

iOS の「視差効果を減らす」/ Android の「アニメーションを削除」をオンにした利用者に、アニメーションをどう出し分けるか。AccessibilityInfo と Reanimated の ReduceMotion を組み合わせ、消すのではなく「穏やかな代替」を返す実装層を作ります。

Reduce Motion2アクセシビリティ3Reanimated9Expo96React Native179

プレミアム記事

ある日、運用している壁紙アプリのレビューに「スライドショーで気分が悪くなる」という一文が付いていました。星は3つ。文面は短く、けれど私自身、しばらく画面を見つめてしまいました。クロスフェードのつもりで作った切り替えに、実際にはわずかな拡大とパララックスを重ねていたのです。端末の「視差効果を減らす」をオンにしている人にとって、その動きは快適どころか負担になっていました。

個人開発でいくつかのアプリを並行して運用していると、こうした「自分の手元では気づけない不具合」に後から気づかされます。Reduce Motion はその典型でした。設定をオンにしている利用者は確実に存在し、その人たちに私たちのアニメーションは届きすぎていたのです。

ここでは、アニメーションを一律に消すのではなく、利用者の設定に応じて「穏やかな代替」を返す層の作り方を、Expo + Reanimated の実装に沿って整理していきます。

端末はどこで Reduce Motion を教えてくれるのか

まず、OS がこの設定をどう公開しているかを押さえます。

iOS では「設定 → アクセシビリティ → 動作 → 視差効果を減らす」が該当します。Android では「設定 → ユーザー補助 → アニメーションを削除」が近い役割を担います。React Native からはどちらも AccessibilityInfo 経由で同じ API で読めます。

import { AccessibilityInfo } from 'react-native';
 
// 現在の状態を一度だけ取得する
const enabled = await AccessibilityInfo.isReduceMotionEnabled();

ここで見落としやすいのが、isReduceMotionEnabled()Promise<boolean> を返す非同期 API である点です。同期的に参照したくなりますが、初回レンダリングの時点ではまだ値が確定していません。さらに、利用者はアプリ起動中に設定を切り替えることがあります。設定アプリへ移動してオンにし、戻ってくる——この往復に追従するには、一度きりの取得ではなく購読が必要です。

起動後の切り替えにも追従する useReducedMotion フック

AccessibilityInfo.addEventListener('reduceMotionChanged', ...) で変更を購読できます。これを小さなフックにまとめます。

import { useEffect, useState } from 'react';
import { AccessibilityInfo } from 'react-native';
 
export function useReducedMotion(): boolean {
  const [reduced, setReduced] = useState(false);
 
  useEffect(() => {
    let mounted = true;
 
    // 初期値を取得(非同期なので await ではなく then で受ける)
    AccessibilityInfo.isReduceMotionEnabled().then((value) => {
      if (mounted) setReduced(value);
    });
 
    // 起動中の切り替えに追従する
    const sub = AccessibilityInfo.addEventListener(
      'reduceMotionChanged',
      (value) => setReduced(value),
    );
 
    return () => {
      mounted = false;
      sub.remove();
    };
  }, []);
 
  return reduced;
}

mounted フラグを置いているのは、isReduceMotionEnabled() の解決前にコンポーネントがアンマウントされたとき、解決後の setReduced が走らないようにするためです。短命な画面で警告が出るのを防ぐ、地味ですが効く一手です。

なお Reanimated は v3.5 以降、同名の useReducedMotion() フックを公式に提供しています。Reanimated を既に使っているなら、そちらを使うのが素直です。自前実装を示したのは、仕組みを理解しておくと「なぜ初回が false になるのか」「なぜ切り替えが反映されるのか」を自分で説明できるようになるからです。

// Reanimated を使っているならこれで十分
import { useReducedMotion } from 'react-native-reanimated';

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
AccessibilityInfo で設定を購読し、起動後の切り替えにも追従する useReducedMotion フックの実装
Reanimated の ReduceMotion.System を使い、アニメーション単位で挙動を出し分ける方法
「全部止める」ではなく、視差・大移動だけを穏やかな代替に置き換える判断表
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

開発ツール2026-06-22
Rork(Expo)のトーストは、重なっても読み上げられても崩れない設計にする
Rork が生成した React Native アプリにトースト通知を足すとき、単純な実装は『同時に2つ出ると重なる』『スクリーンリーダーに無視される』『ノッチやホームインジケータに隠れる』の3点で破綻します。ルート1か所に置くキュー設計、本体の再レンダーから切り離すアニメーション、AccessibilityInfo による読み上げ、セーフエリア対応までを動くコードで示します。
開発ツール2026-05-20
Rork で VoiceOver と Dynamic Type を本番品質に整える実装メモ
Rork で出力した React Native アプリに VoiceOver・Dynamic Type・Reduce Motion を本番品質で組み込むための、ラベル設計・フォーカス管理・回帰テストまで含めた実装メモです。
開発ツール2026-06-23
価格が一部の端末だけ「¥1234」になる——Expo の Intl を信用しきらないフォーマット層の作り方
同じコードなのに、ある端末では「¥1,234」、別の端末では「¥1234」。Expo / Hermes の Intl は端末とOSのロケールデータに依存して出力が変わります。通貨・数値・日付・タイムゾーンを1ファイルに集約し、Intl が欠ける端末へ安全に後退するフォーマット層の設計を、動くコードで整理しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →