react-native使用动画Animated

本文介绍了如何在ReactNative应用中使用Animated组件和linear-gradient创建一个动态效果,即一个从左向右移动并逐渐透明的亮光块。作者展示了如何设置动画值、使用interpolate函数映射动画值以及控制阴影组件的透明度。
摘要由CSDN通过智能技术生成

官方网文档:动画Animated
一些精彩的例子:React Native 动画(Animated)
渐变组件的使用:ReactNative 进阶(四十五):渐变组件 react-native-linear-gradient

需要实现如下的动画动画效果:

shinebutton

进行拆分:

  • 亮光从左到右位置的移动 ==〉可以用marginLeft的值改变来展示 ==〉使用react-native的Animated方法
  • 当亮光移动到按钮的最右边的时候,透明度应该为0
  • 亮光是一个倾斜状的渐变白色块状 ===〉使用react-native-linear-gradient组件,包含对颜色的透明度

react-native的Animated方法:

  const animatedValue = React.useRef(new Animated.Value(0)).current; // 创建value
  const marginLeft = animatedValue.interpolate({
    inputRange: [0, 1], // 当animatedValue的值从0变化到1的时候
    outputRange: [0, 300], // marginLeft则从0变化到300
  });
    // opacity will be 0 if the shine view removed right
  const opacity = animatedValue.interpolate({
    inputRange: [0, 1],
    outputRange: [1, 0], // 透明度变化
    extrapolate: 'clamp',
  });
  const rotateAnimated = Animated.timing(animatedValue, { // 必有,时间序列变化函数
    toValue: 1, // 最终值
    duration: 500, // 动画的持续时间(毫秒)
    easing: Easing.in, // 缓动函数
  });
  rotateAnimated.start(); // 开始执行动画
  • interpolate函数,可以将动画值从一个范围映射到另一个范围。

react-native-linear-gradient组件:

<LinearGradient
 start={{ x: 0, y: 0.2 }}
 end={{ x: 0.8, y: 1 }}
 colors={['rgba(255, 255, 255, 0)', 'rgba(255, 255, 255, 0.5)', 'rgba(255, 255, 255, 0)']}
 style={[styles.shadowView, { width: height }]}
/>
  • 可以进行透明度。

完整代码:

import React, { memo, useEffect } from 'react';
import {
  Animated,
  Easing,
  StyleSheet,
  Text,
  TextStyle,
  TouchableWithoutFeedback,
  View,
  ViewStyle,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';

export interface ShineButtonProps {
  buttonText: string;
  buttonTextStyle?: TextStyle;
  buttonViewStyle: ViewStyle & { width: number; height: number }; // width and height are required
  onPress: () => void;
}

const ShineButton = ({
  buttonText,
  buttonTextStyle,
  buttonViewStyle,
  onPress,
}: ShineButtonProps) => {
  const { width, height } = buttonViewStyle;

  const animatedValue = React.useRef(new Animated.Value(0)).current;
  const marginLeft = animatedValue.interpolate({ // 映射函数
    inputRange: [0, 1],
    outputRange: [0, width],
  });
  // opacity will be 0 if the shine view removed right
  const opacity = animatedValue.interpolate({
    inputRange: [0, 1],
    outputRange: [1, 0],
    extrapolate: 'clamp',
  });
  const rotateAnimated = Animated.timing(animatedValue, { // 必有,时间变化函数
    toValue: 1,
    duration: 500,
    easing: Easing.in,
  });

  useEffect(() => {
    rotateAnimated.start(); // 开始执行动画
  });

  return (
    <View style={styles.viewContainer}>
      <TouchableWithoutFeedback
        style={styles.buttonContainer}
        onPress={onPress}
      >
        <View style={[styles.buttonView, buttonViewStyle]}>
          <Text style={[styles.buttonText, buttonTextStyle]}>{buttonText}</Text>
        </View>
      </TouchableWithoutFeedback>
      <Animated.View
        style={[
          styles.animatedContainer,
          {
            marginLeft, // 使用
            width: height,
            height,
            opacity,
          },
        ]}
      >
        <LinearGradient
          start={{ x: 0, y: 0.2 }}
          end={{ x: 0.8, y: 1 }}
          colors={['rgba(255, 255, 255, 0)', 'rgba(255, 255, 255, 0.5)', 'rgba(255, 255, 255, 0)']}
          style={[styles.shadowView, { width: height }]}
        />
      </Animated.View>
    </View>
  );
};

export default memo(ShineButton);

const styles = StyleSheet.create({
  viewContainer: {
    flex: 1,
    position: 'relative',
  },
  buttonContainer: {
    zIndex: 2,
  },
  animatedContainer: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    zIndex: 1,
  },
  shadowView: {
    position: 'absolute',
    top: 0,
    bottom: 0,
  },
  buttonView: {
    backgroundColor: Colors.white,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
  },
  buttonText: {
    color: Colors.primary,
    ...TypographyFontPreset.R14,
    fontWeight: '900',
  },
});
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在React Native中实现动画放大,可以使用Animated API。具体步骤如下: 1. 导入Animated API和需要使用的组件,例如Image。 2. 创建一个新的Animated.Value,用于存储动画的值。 3. 在组件的样式中使用Animated.Value作为transform属性的scale值。 4. 创建一个动画函数,使用Animated.timing()方法来控制动画的时间和值。 5. 在需要触发动画的事件中调用动画函数。 下面是一个简单的例子,演示如何在React Native中实现动画放大: ```javascript import React, { Component } from 'react'; import { View, Image, Animated } from 'react-native'; export default class App extends Component { constructor(props) { super(props); this.state = { scaleValue: new Animated.Value(1), }; } handlePress = () => { Animated.timing(this.state.scaleValue, { toValue: 2, duration: 1000, useNativeDriver: true, }).start(); }; render() { const { scaleValue } = this.state; return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Animated.Image source={{ uri: 'https://picsum.photos/200/300' }} style={{ width: 200, height: 300, transform: [{ scale: scaleValue }] }} /> </View> ); } } ``` 在上面的例子中,我们创建了一个新的Animated.Value,命名为scaleValue,并将其初始值设置为1。在组件的样式中,我们使用Animated.Value作为transform属性的scale值,这样就可以通过改变scaleValue的值来实现动画放大。在handlePress函数中,我们使用Animated.timing()方法来控制动画的时间和值,当触发事件时,调用动画函数即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值