animation动画不生效_react animation -- 基于现有组件库封装动画组件

本文旨在为React组件添加动画效果,通过记录状态控制类名实现鼠标移入移出的动画。在使用display:none进行隐藏时,动画效果会失效。通过引入CSSTransition库并利用unmountOnExit属性,解决了动画组件在关闭时动画失效的问题。最后,展示了如何封装一个类似Icon的动画组件,提供便捷的动画效果配置。
摘要由CSDN通过智能技术生成

7a7191ead5f47497a2ae5b2ebccf83ef.png

目标:为react组件轻松的添加动画效果。

<Transition
  in={ flag } // 控制动画展示的变量
  timeout={ 300 } // 动画持续时间
  animation='zoom-in-top‘
>
  { node }
</Transition>

拿导航栏的鼠标移入效果举例:

6d5d84ff10a5f6cf6ca0d6ec177771dd.png

鼠标移入时,下拉框展示,箭头向上旋转180;鼠标移出时,箭头向下旋转180,然后弹出层消失。

解决方案: 记录一个状态,当鼠标点击时,给这个元素添加一个类名,再次点击时,取消这个类名。

现在添加css效果,一开始的时候,ul是不展示的,即不显示在页面中。让元素不显示在页面中有两种方法:

  1. 元素存在于页面,但是看不见,使用opacity属性,设置为0
  2. 使用display:none,让元素不存在于页面。

这里初始的时候,显然只能使用第二种,因为第一种容易发生误点的情况。

但是这种情况存在一个问题,就是当组件再次点击消失的时候,display属性设置为none之后,其动画效果失效了,所以会导致在再次点击关闭的时候没有动画效果。

所以此时,我们引入第三方的动画插件库,来帮助我们解决这个问题.

  1. 快速上手使用CSSTransition
yarn add react-transition-group
yarn add @types/react-transition-group
import { CSSTransitionGroup } from 'react-transition-group'

<CSSTransition 
  in={inProp} 
  timeout={200} 
  classNames="my-node”
>
  <div>
    hello world
  </div>
</CSSTransition>

然后在样式组件上写入:

.my-node-enter {
  opacity: 0;
}
.my-node-enter-active {
  opacity: 1;
  transition: opacity 200ms;
}
.my-node-exit {
  opacity: 1;
}
.my-node-exit-active {
  opacity: 0;
  transition: opacity 200ms;
}

这样就给hello world元素添加上了一个简单动画。

2. 使用CSSTransition解决刚才的问题

因为该组件库有一个属性,unmountOnExit,即当in属性变化时,如果变为true,则会在当前页面渲染出内部元素,当为false时,会自动删除其中的节点。

所以我们将该属性附上,并添加一个appear属性,当初始化时动画也生效

<CSSTransition 
  in={inProp} 
  timeout={200} 
  classNames="my-node”
  unmountOnExit
  appear
>
  <div>
    hello world
  </div>
</CSSTransition>

3. 接下来,我们对于该组件做一次类似Icon组件的二次封装,将通用的属性设置为默认属性,并提供一些常用的动画效果

import React from 'react'
import { CSSTransition } from 'react-transition-group'
import { CSSTransitionProps } from 'react-transition-group/CSSTransition'

type TAnimationName = 'zoom-in-top' | 'zoom-in-left'

type TransitionProps = CSSTransitionProps & {
    animation?: TAnimationName,
    wrapper? : boolean,
  }

const Transition: React.FC<TransitionProps> =  (props) => {
    const { children, classNames, animation, wrapper, ...restProps } = props
    console.log('classNames', classNames);
    console.log('animation', animation);
    
    return (
        <CSSTransition
            classNames={classNames ? classNames : animation}
            {...restProps}
        >
            { children }
        </CSSTransition>
    )
}

Transition.defaultProps = {
    unmountOnExit: true,
    appear: true,
  }

export default Transition

这样我们就能够使用方便的动画效果:

<Transition
  in={ flag } // 控制动画展示的变量
  timeout={ 300 } // 动画持续时间
  animation='zoom-in-top‘
>
  { node }
</Transition>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值