wcandillon / react-native-redash

The React Native Reanimated and Gesture Handler Toolbelt
https://wcandillon.gitbook.io/redash/
MIT License
1.97k stars 117 forks source link

Trigger action when state of panHandler change #296

Open felire opened 4 years ago

felire commented 4 years ago

Hi, I'm using this: const { gestureHandler, state, translation, velocity } = panGestureHandler();

from this library.

I have the following question, how can I trigger an action when the state change? I would like to start a timer when state change to ACTIVE and put the timer to 0 when the state is END or something else. Then I would like to use that timer to enable another animations when it has happened X time.

terrysahaidak commented 4 years ago

where do you need to start the timer? in your animation code or in js?

you can use useCode hook and either onChange block to callback to js or some cond nodes to execute some logic.

felire commented 4 years ago

I need to start the timer when the state change from any other state to ACTIVE. I tried with useCode an inside of it I tried to use the cond and eq to compare values but it does not work, it doesn't trigger anything

terrysahaidak commented 4 years ago

could you post some code?

felire commented 4 years ago

@terrysahaidak Yes, I extract the code from a video of @wcandillon where he made a chrome tabs handler. Video

This is the code:

import React, { useState, useEffect } from 'react';
import Animated from 'react-native-reanimated';
import { PanGestureHandler, State } from 'react-native-gesture-handler';
import { moving, panGestureHandler, withSpringTransition } from 'react-native-redash';

import PhotoItem, { PhotoItemProps } from '../PhotoItem';
import { TAB_WIDTH_DELTA, TAB_WIDTH, TAB_HEIGHT, TAB_HEIGHT_DELTA } from '../../constants';

const { Value, add, cond, eq, block, set, useCode, multiply, divide, and, round } = Animated;

export const withOffset = ({
  offset,
  value,
  state: gestureState
}: {
  offset: Animated.Adaptable<number>;
  value: Animated.Value<number>;
  state: Animated.Value<State>;
}) => {
  const safeOffset = new Value(0);
  return cond(eq(gestureState, State.ACTIVE), add(safeOffset, value), set(safeOffset, offset));
};

interface SortablePhotoItemProps extends PhotoItemProps {
  index: number;
  offsets: { x: Animated.Value<number>; y: Animated.Value<number> }[];
}

export default ({ image, offsets, index, onImageSelected }: SortablePhotoItemProps) => {
  const { gestureHandler, state, translation, velocity } = panGestureHandler();
  const currentOffset = offsets[index];
  const x = withOffset({
    value: translation.x,
    offset: currentOffset.x,
    state
  });
  const y = withOffset({
    value: translation.y,
    offset: currentOffset.y,
    state
  });
  const zIndex = cond(eq(state, State.ACTIVE), 200, cond(moving(y), 100, 1));
  const offsetX = multiply(round(divide(x, TAB_WIDTH_DELTA)), TAB_WIDTH_DELTA);
  const offsetY = multiply(round(divide(y, TAB_HEIGHT_DELTA)), TAB_HEIGHT_DELTA);
  const translateX = withSpringTransition(x, {}, velocity.x, state);
  const translateY = withSpringTransition(y, {}, velocity.y, state);

  useCode(
    () =>
      block(
        offsets.map(offset =>
          cond(and(eq(offsetX, offset.x), eq(offsetY, offset.y), eq(state, State.ACTIVE)), [
            set(offset.x, currentOffset.x),
            set(offset.y, currentOffset.y),
            set(currentOffset.x, offsetX),
            set(currentOffset.y, offsetY)
          ])
        )
      ),
    [currentOffset.x, currentOffset.y, offsetX, offsetY, offsets, state]
  );
  return (
    <PanGestureHandler {...gestureHandler}>
      <Animated.View
        style={{
          position: 'absolute',
          top: 0,
          left: 0,
          width: TAB_WIDTH,
          height: TAB_HEIGHT,
          transform: [{ translateX }, { translateY }],
          zIndex
        }}>
        <PhotoItem {...{ image, onImageSelected }} />
      </Animated.View>
    </PanGestureHandler>
  );
};

I really don't know how to do this

RobertPechaCZ commented 4 years ago

This way worked for me: ` import { diff, useClocks, useValues, ............ } from 'react-native-redash';

const [timer] = useClocks(1); const [timerOffset] = useValues(1); ................... useCode(() => [ cond(and(neq(diff(state), 0), eq(state, State.ACTIVE)), [ startClock(timer), set(timerOffset, timer), ]), .... .... ], []); `

akshgods commented 1 year ago

@RobertPechaCZ can you give full code or demo for this. im looking for same