React 实现未知高度元素收缩展开动画过渡效果

通过使用React库 react-transition-groupTransition来实现对未知高度的元素进行展开收缩动画过渡效果实现。

1. 安装 react-transition-group

npm install react-transition-group --save
or
pnpm add react-transition-group

2. 使用 Transition 实现

属性介绍

  • in
    表示元素是否处于进入状态或离开状态。如果为 true,则表示元素处于进入状态,反之,则表示元素处于离开状态。

  • timeout
    表示动画执行的时间。可以设置为数字,也可以设置为对象,分别表示进入和离开动画的执行时间。

  • appear
    表示是否在组件首次挂载时执行进入动画。如果为 true,则表示首次挂载时会执行进入动画。

  • mountOnEnter
    表示在进入动画开始时,组件需要挂载到 DOM 上。

  • unmountOnExit
    表示在离开动画结束时,组件需要从 DOM 上卸载。

Transition 事件介绍:

react-transition-group 的 Transition 组件提供了一些事件,可以让我们在动画执行过程中执行一些自定义操作。以下是一些 Transition 组件提供的事件:

  • onEnter(node: HTMLElement, isAppearing: boolean)
    在元素进入动画开始之前触发,可以在此时对元素进行一些自定义的操作。

  • onEntering(node: HTMLElement, isAppearing: boolean)
    在元素进入动画执行中触发,可以在此时对元素进行一些自定义的操作。

  • onEntered(node: HTMLElement, isAppearing: boolean)
    在元素进入动画完成之后触发,可以在此时对元素进行一些自定义的操作。

  • onExit(node: HTMLElement)
    在元素离开动画开始之前触发,可以在此时对元素进行一些自定义的操作。

  • onExiting(node: HTMLElement)
    在元素离开动画执行中触发,可以在此时对元素进行一些自定义的操作。

  • onExited(node: HTMLElement)
    在元素离开动画完成之后触发,可以在此时对元素进行一些自定义的操作。

实现代码

const AA = () => {
  const [isOpen, setIsOpen] = useState(false);
  
  const onClick = () => {
    setIsOpen((open) => !open);
  };
  
  const onEnter = (el) => {
    el.style.transition = '0.3s max-height ease';
    el.style.maxHeight = '0px';
    el.style.overflow = 'hidden';
  };
  
  const onEntering = (el) => {
    el.style.maxHeight = el.scrollHeight + 'px';
  };
  
  const onEntered = (el) => {
    el.style.transition = '';
    el.style.maxHeight = '';
  };
  
  const onExit = (el) => {
    el.style.overflow = 'hidden';
    el.style.maxHeight = el.scrollHeight + 'px';
  };
  
  const onExiting = (el) => {
    if (el.scrollHeight !== 0) {
      el.style.transition = '0.3s max-height ease';
      el.style.maxHeight = '0px';
    }
  };
  
  const onExited = (el) => {
    el.style.transition = '';
    el.style.maxHeight = '';
  };
  
  return (
    <div>
      <button type="button" onClick={onClick}>
        {isOpen ? '收起' : '展开'}
      </button>
      <Transition in={isOpen} timeout={300} unmountOnExit onEnter={onEnter} onEntering={onEntering} onEntered={onEntered} onExit={onExit} onExiting={onExiting} onExited={onExited}>
        <div style={{ width: 200 }}>
          这是内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
        </div>
      </Transition>
    </div>
  );
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在 React Native 中实现元素波纹扩散动画,你可以使用 `TouchableWithoutFeedback` 组件和 `Animated` API。 首先,你需要导入 `TouchableWithoutFeedback` 和 `Animated`: ```javascript import React, { Component } from 'react'; import { TouchableWithoutFeedback, Animated } from 'react-native'; ``` 然后,你需要创建一个 `Animated.Value`,用于控制扩散动画的半径: ```javascript class Ripple extends Component { radius = new Animated.Value(0); // ... } ``` 接下来,你需要在 `TouchableWithoutFeedback` 的 `onPress` 和 `onPressIn` 事件中触发扩散动画。在 `onPressIn` 中,你可以使用 `Animated.timing` 函数来使半径从 0 扩大到最大值,然后在 `onPress` 中使用 `Animated.timing` 函数使半径恢复到 0。 ```javascript class Ripple extends Component { onPressIn = () => { Animated.timing(this.radius, { toValue: 1, duration: 500, }).start(); }; onPress = () => { Animated.timing(this.radius, { toValue: 0, duration: 500, }).start(); }; render() { const { children, style } = this.props; const rippleStyle = { borderRadius: 1000, position: 'absolute', top: 0, left: 0, width: this.radius.interpolate({ inputRange: [0, 1], outputRange: [0, 500], }), height: this.radius.interpolate({ inputRange: [0, 1], outputRange: [0, 500], }), opacity: this.radius.interpolate({ inputRange: [0, 1], outputRange: [0.5, 0], }), }; return ( <TouchableWithoutFeedback onPress={this.onPress} onPressIn={this.onPressIn}> <Animated.View style={[style, { overflow: 'hidden' }]}> {children} <Animated.View style={[rippleStyle]} /> </Animated.View> </TouchableWithoutFeedback> ); } } ``` 最后,你可以在你的组件中使用 `Ripple` 组件来实现元素波纹扩散动画: ```javascript class App extends Component { render() { return ( <View style={styles.container}> <Ripple style={styles.button}> <Text style={styles.text}>Press me</Text> </Ripple> </View> ); } } ``` 这样就可以在按下按钮时触发元素波纹扩散动画了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顺芯技术猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值