Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React Nativeでアニメーションを頑張る- React Native Meetup #11

3aae47c11fab74b1db6ec80cd6f49058?s=47 takahi5
March 04, 2021

React Nativeでアニメーションを頑張る- React Native Meetup #11

React Nativeのアニメーション、こんなときはどう実装する?
パターンごとに考えてみます。

1. 固定アニメ
2. 細かいインタラクション
3. スクロールと連動した演出
4. スワイプと連動した演出

3aae47c11fab74b1db6ec80cd6f49058?s=128

takahi5

March 04, 2021
Tweet

Transcript

  1. React Nativeで アニメーションを頑張る 和田崇彦 @takahi5 stand.fm 2021.3.4 React Native Meetup

    #11
  2. 自己紹介
 - stand.fmのエンジニア 
 - React Native Japan運営
 - UdemyでReact

    Nativeのコース
 和田 崇彦 @takahi5
 2
  3. stand.fm stand.fmは誰でもかんたんに
 アプリで収録・LIVE配信ができる音声 プラットフォームです
 
 3

  4. stand.fm 4 React Native Japanのラジオ もあります! 技術情報, エンジニアインタ ビュー ...etc

    毎日ピザパ🍕 React Native Japan 個人で 無益な情報発信も...
  5. 今日話すこと
 React Nativeでアニメーションを頑張る
 
 こういうときはどうする?
 パターンごとに考えてみる
 5

  6. ① 固定アニメ
 
 
 6

  7. ① 固定アニメ ローディングのグルグル 何かの完了演出 決まったアニメーションを再生し続ける 7

  8. Lottie • airbnbが開発したアニメーションライブラリ • Adobe After Effectsで作る 8

  9. LottieFiles • Lottie用のデータのマーケットプレイ ス • 無料データも豊富♪ https://lottiefiles.com 9

  10. Lottie vs アニメーションgif 💡 Lottieメリット • 拡大してもきれい(ベクターデータ) • 軽量 (右の例だと...

    108KB vs 1.3MB) • サクサク動く 10
  11. ② 細かいインタラクション
 
 
 11

  12. ② 細かいインタラクション • アイテムをフェードインで フワッと出したい • タップしたときにボヨヨンとさせたい ...などなど ここを フワッと出したい

    (地味に大変そう...) 12
  13. moti • reanimated 2ベースのライブラリ • 直感的なAPI • ExpoやWebもサポート • ちょっとした演出の実装に便利

    ✨ 13
  14. フェードの有無
 なし あり 14

  15. フェードなし ViewをMoti.Viewに差し替える + 演出の具合を指定 フェードあり motiの導入 15

  16. ③ スクロールと連動した演出
 
 
 16

  17. ヘッダーの高さ ヘッダー画像のボカし アバター画像のサイズ・位置 アバター画像の重なり順 17

  18. const scrollY = useRef(new Animated.Value(0)).current; return ( <View style={styles.container}> <ScrollView

    scrollEventThrottle={16} onScroll={Animated.event( [{ nativeEvent: { contentOffset: { y: scrollY } } }], )} > onScrollイベントで取得したスクロール量を、 アニメ用の変数ScrollYに割り当てる 18
  19. scrollYに連動させて各種値を変化させる interpolateでinput→outputを調整する height: scrollY.interpolate({ inputRange: [0, 50], outputRange: [200, 100],

    extrapolate: "clamp", }), 19
  20. 例) ヘッダー高さ - はじめは高さ150 - スクロールに比例して低くなる - 高さ80になったら固定 scrollY ヘッダーheight

    height: scrollY.interpolate({ inputRange: [0, 70], outputRange: [150, 80], extrapolate: "clamp", }), 150 80 70 20
  21. scrollY アバター位置Y scrollY 画像のぼかし 1 scrollY アバター zIndex 10 0

    0 他の値についても scrollYとの関係をコードに落とし込めばOK 21
  22. ④ スワイプと連動した演出
 
 
 22

  23. tinder風UI 23

  24. const pan = useRef(new Animated.ValueXY()).current; const panResponder = PanResponder.create({ onPanResponderMove:

    () => 動かしたとき, onPanResponderRelease: () => 離したとき, }) return ( <Animated.View {...panResponder.panHandlers} > ) PanResponder でスワイプ時の動きを取得 あとはScrollのときと同じ要領で 24
  25. pan dx, dy カード位置 dx, dx pan dx カード回転 θ

    カード位置と回転量を スワイプに連動させる 25
  26. 指を離したとき→画面外へ飛ばす or もとに戻す const panResponder = PanResponder.create({ onPanResponderRelease: (e, gestureState)

    => { if (gestureState.dx > SWIPE_THRESHOLD) { // 右へ飛ばす Animated.timing(pan, { toValue: { x: 500, y: gestureState.dy - 200 }, }).start(); } else if (gestureState.dx < -SWIPE_THRESHOLD) { // 左へ飛ばす Animated.timing(pan, { toValue: { x: -500, y: gestureState.dy - 200 }, }).start()); } else { // 元の位置に戻す Animated.spring(pan, { toValue: { x: 0, y: 0 }, }).start(); } }, }); 26
  27. まとめ
 • 固定アニメ、デザインが要求されるもの 
 → Lottie
 • 細かいインタラクション 
 →

    motiが便利そう!
 • スクロールやスワイプに連動した演出 
 → Animatedで実装可能。interpolateは分解して考える 
 27 サンプルコード: https://github.com/takahi5/react-native-animation-showcase