Как сделать простую анимацию непрозрачности, используя функциональные компоненты и реагировать на реанимацию - PullRequest
0 голосов
/ 07 марта 2020

Каждый реанимированный документ реагирования использует компоненты класса. Я пытался изменить способ создания простой анимации непрозрачности кнопки, но я не могу заставить себя работать, кажется, набор не работает, если я изменяю на Opacity.setvalue (0), он работает, но мне нужно установить его, чтобы использовать часы для других анимаций, любая помощь, пожалуйста.

import React, { useState } from "react";
import { View, Text, StyleSheet, Image, Dimensions } from "react-native";
import Animated, { Easing } from "react-native-reanimated";
import { TapGestureHandler, State } from "react-native-gesture-handler";

function MusicApp() {
  const {
    Value,
    Clock,
    startClock,
    stopClock,
    debug,
    timing,
    clockRunning,
    block,
    cond,
    set,
    eq
  } = Animated;


  const { width, height } = Dimensions.get("window");
  const [buttonOpacity, setbuttonOpacity] = useState(1);

 const Opacity = new Value(1);   



  function onStateChange() {
    Animated.event([
      {
        nativeEvent: ({state}) =>
          Animated.block([cond(eq(state, State.END),set(Opacity,0) )
          ])
      }
    ]);
  }

  return (
    <View style={{ backgroundColor: "black", justifyContent: "flex-end" }}>
      <View
        style={{ position: "absolute", top: 0, bottom: 0, left: 0, right: 0 }}
      >
        <Image
          source={require("../assets/bg.jpg")}
          style={{ height: height, width: width }}
        />
      </View>

      <View style={{ height: height / 3, justifyContent: "center" }}>
        <TapGestureHandler
          onHandlerStateChange={() => {
            onStateChange();
          }}
        >
          <Animated.View style={{ ...styles.button, opacity: Opacity}}>
            <Text style={{ fontSize: 20 }}>SIGN IN</Text>
          </Animated.View>
        </TapGestureHandler>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center"
  },
  button: {
    backgroundColor: "red",
    height: 70,
    marginHorizontal: 20,
    borderRadius: 35,
    alignItems: "center",
    justifyContent: "center"
  },
  button2: {
    backgroundColor: "blue",
    height: 70,
    marginHorizontal: 20,
    borderRadius: 35,
    alignItems: "center",
    justifyContent: "center"
  }
});

export default MusicApp;

Ответы [ 2 ]

0 голосов
/ 07 марта 2020

Реанимированный использует декларативный api, а не императивный api по умолчанию Animated api т.е. отметка времени для каждого кадра.

с помощью этих часов вы можете определить вспомогательные функции, такие как

function runTiming(clock, value, dest) {
  const state = {
    finished: new Value(0),
    position: new Value(0),
    time: new Value(0),
    frameTime: new Value(0),
  };

  const config = {
    duration: 5000,
    toValue: new Value(0),
    easing: Easing.inOut(Easing.ease),
  };

  return block([
    cond(
      clockRunning(clock),
      [
        // if the clock is already running we update the toValue, in case a new dest has been passed in
        set(config.toValue, dest),
      ],
      [
        // if the clock isn't running we reset all the animation params and start the clock
        set(state.finished, 0),
        set(state.time, 0),
        set(state.position, value),
        set(state.frameTime, 0),
        set(config.toValue, dest),
        startClock(clock),
      ]
    ),
    // we run the step here that is going to update position
    timing(clock, state, config),
    // if the animation is over we stop the clock
    cond(state.finished, debug('stop clock', stopClock(clock))),
    // we made the block return the updated position
    state.position,
  ]);
}

, а в компоненте существует несколько способов анимации значения.

я рекомендовал использовать Code или useCode из реанимированного

, вы можете использовать его как

function OpacityButton ({}){
 const opacity = new Value(1)
 const clock = new Clock()
 const clicked = new Value(0)
 const buttonState = new Value()
 useCode(() => block([cond(eq(clicked,1),[
  set(opacity, runTiming(clock, opacity, 0.5)
])]))
 return (

  <TouchableOpacity onPress={() => clicked.setValue(1)} >
     <Animated.View style={[styles.button,{opacity}]} />
  </TouchableOpacity>
 )
}

это всего лишь 70% кода. Но вы можете расширить его по своему требованию.

0 голосов
/ 07 марта 2020

Вы можете сопоставить состояние нажатия кнопки с переменной tap. Затем вы можете использовать хук useCode с tap в качестве зависимости и изменить непрозрачность соответственно с 1 на 0.

const {height} = Dimensions.get("window")
const { eq, useCode, timing, Clock, Value, set, cond} = Animated

const App = () => {
  const [tap, setTap] = useState(new Value(-1))
  const opacity = new Value(1)
  const handleChange = e => {
    tap.setValue(e.nativeEvent.state)
  }

  useCode(() => (
    cond(eq(tap, State.BEGAN), set(opacity, 0), 0)
  ), [tap])
  return (
    <>
      <View style = {{height: height/3, justifyContent: "flex-end", backgroundColor: "green"}}>
        <TapGestureHandler onHandlerStateChange = {handleChange}>
          <Animated.View style = {{...styles.button, opacity: opacity}}>
            <Text style = {{fontSize: 20}}>SIGN IN</Text>
          </Animated.View>
        </TapGestureHandler>
      </View>
    </>
  );
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...