Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

自己紹介
 - stand.fmのエンジニア 
 - React Native Japan運営
 - UdemyでReact Nativeのコース
 和田 崇彦 @takahi5
 2

Slide 3

Slide 3 text

stand.fm stand.fmは誰でもかんたんに
 アプリで収録・LIVE配信ができる音声 プラットフォームです
 
 3

Slide 4

Slide 4 text

stand.fm 4 React Native Japanのラジオ もあります! 技術情報, エンジニアインタ ビュー ...etc 毎日ピザパ🍕 React Native Japan 個人で 無益な情報発信も...

Slide 5

Slide 5 text

今日話すこと
 React Nativeでアニメーションを頑張る
 
 こういうときはどうする?
 パターンごとに考えてみる
 5

Slide 6

Slide 6 text

① 固定アニメ
 
 
 6

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

② 細かいインタラクション
 
 
 11

Slide 12

Slide 12 text

② 細かいインタラクション ● アイテムをフェードインで フワッと出したい ● タップしたときにボヨヨンとさせたい ...などなど ここを フワッと出したい (地味に大変そう...) 12

Slide 13

Slide 13 text

moti ● reanimated 2ベースのライブラリ ● 直感的なAPI ● ExpoやWebもサポート ● ちょっとした演出の実装に便利 ✨ 13

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

const scrollY = useRef(new Animated.Value(0)).current; return ( onScrollイベントで取得したスクロール量を、 アニメ用の変数ScrollYに割り当てる 18

Slide 19

Slide 19 text

scrollYに連動させて各種値を変化させる interpolateでinput→outputを調整する height: scrollY.interpolate({ inputRange: [0, 50], outputRange: [200, 100], extrapolate: "clamp", }), 19

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

scrollY アバター位置Y scrollY 画像のぼかし 1 scrollY アバター zIndex 10 0 0 他の値についても scrollYとの関係をコードに落とし込めばOK 21

Slide 22

Slide 22 text

④ スワイプと連動した演出
 
 
 22

Slide 23

Slide 23 text

tinder風UI 23

Slide 24

Slide 24 text

const pan = useRef(new Animated.ValueXY()).current; const panResponder = PanResponder.create({ onPanResponderMove: () => 動かしたとき, onPanResponderRelease: () => 離したとき, }) return ( ) PanResponder でスワイプ時の動きを取得 あとはScrollのときと同じ要領で 24

Slide 25

Slide 25 text

pan dx, dy カード位置 dx, dx pan dx カード回転 θ カード位置と回転量を スワイプに連動させる 25

Slide 26

Slide 26 text

指を離したとき→画面外へ飛ばす 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

Slide 27

Slide 27 text

まとめ
 ● 固定アニメ、デザインが要求されるもの 
 → Lottie
 ● 細かいインタラクション 
 → motiが便利そう!
 ● スクロールやスワイプに連動した演出 
 → Animatedで実装可能。interpolateは分解して考える 
 27 サンプルコード: https://github.com/takahi5/react-native-animation-showcase