Open5

React Spring関連

jintzjintz

React Native Gesture Handler

  • Gesture.Fling()
    • いわゆるフリック動作
  • Gesture.Race()
    • 複数のジェスチャーをまとめる
  • Gesture.Manual()
    • 細かく動作に応じた処理を設定したい場合に使う?
jintzjintz
import React, { useState } from 'react';
import { useSpring, animated } from '@react-spring/native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';

export const Hoge = () => {
  const [{ initialX, initialY }, setInitial] = useState({ initialX: 0, initialY: 0 });
  const [{ mx, my }, api] = useSpring(() => ({ mx: 0, my: 0 }));

  const gesture = Gesture.Manual()
    .onTouchesDown(e => setInitial({ initialX: e.changedTouches[0].x, initialY: e.changedTouches[0].y }))
    .onTouchesMove(e => {
      const touch = e.changedTouches[0];
      api.start({ mx: touch.x - initialX, my: touch.y - initialY });
    })
    .onTouchesUp(() => api.start({ mx: 0, my: 0 }));

  return (
    <GestureDetector gesture={gesture}>
      <animated.Image
        style={[styles.image, { transform: [{ translateX: mx }, { translateY: my }] }]}
        source={require('./hoge.jpg')
      />
    </GestureDetector>
  );
};

こんな感じで画像をぐりぐり動かせるようになる。

jintzjintz

web version (@react-spring/web) における xytransform: [{ translateX: x }, { translate: y }] の糖衣構文っぽい。実際には多分諸所の問題解決や微調整を含んでいるだろうけど。
ともかく、React Native上で上下左右の移動量を定義したい場合は transform を利用すればいい。

jintzjintz

https://docs.swmansion.com/react-native-gesture-handler/docs/under-the-hood/states-events

The flow looks as follows (longer arrows represent that there are possibly more touch events received before the state changes):

UNDETERMINED -> BEGAN ------> ACTIVE ------> END -> UNDETERMINED

Another possible flow is when a handler receives touches that cause a recognition failure:

UNDETERMINED -> BEGAN ------> FAILED -> UNDETERMINED

At last, when a handler does properly recognize the gesture but then is interrupted by the touch system the gesture recognition is canceled and the flow looks as follows:

UNDETERMINED -> BEGAN ------> ACTIVE ------> CANCELLED -> UNDETERMINED

普通にやる分にはActiveで開始処理、Endで終了処理で良さそう。

jintzjintz

https://docs.swmansion.com/react-native-gesture-handler/docs/api/gestures/fling-gesture

onBegin(callback)
Set the callback that is being called when given gesture handler starts receiving touches. At the moment of this callback the handler is not yet in an active state and we don't know yet if it will recognize the gesture at all.

onStart(callback)
Set the callback that is being called when the gesture is recognized by the handler and it transitions to the active state.

onEnd(callback)
Set the callback that is being called when the gesture that was recognized by the handler finishes. It will be called only if the handler was previously in the active state.

実際にはActiveになるときにonStartが発火するっぽい。