React框架(十)动画效果实现的两种方式

1.使用CSS实现动画

本例中,只保留了App这一个组件,代码如下:

import React, {Component, Fragment} from 'react';
import './style.css' //引入的CSS文件
class App extends Component {

    constructor(props) {
        super(props);
        this.state = {
            show: true // 控制hello是否显示
        };
        this.handleToggle = this.handleToggle.bind(this);
    }

    render() {
        return (
            <Fragment>
            {/*根据show的真值修改类名*/}
                <div className={this.state.show ? 'show' : 'hide'}>hello</div>
                <button onClick={this.handleToggle}>toggle</button>
            </Fragment>
        )
    }

    // 让show不断变换真值
    handleToggle() {
        this.setState({
            show: this.state.show ? false : true
        })
    }
}

export default App;

style.css文件:

.show{
    opacity: 1;
    transition: all 1s ease-in;
}
.hide{
    opacity: 0;
    transition: all 1s ease-in;
}

如果实现动画,也可以使用keyframe

.show{
    animation: show-item 2s ease-in forwards;
}
.hide{
    /*forwards 使得动画效果保留最后一帧,即hide-item进行到100%的样式*/
    animation: hide-item 2s ease-in forwards;
}

@keyframes show-item {
    0%{
        opacity: 0;
        color: red;
    }
    50%{
        opacity: 0.5;
        color: green;
    }
    100%{
        opacity: 1;
        color: blue;
    }
}

@keyframes hide-item {
    0%{
        opacity: 1;
        color: red;
    }
    50%{
        opacity: 0.5;
        color: green;
    }
    100%{
        opacity: 0;
        color: blue;
    }
}

demo地址: React-TodoList示例——CSS的使用

2.使用react-transition-group实现动画

这是一个js框架,源码地址:react-transition-group

  1. 使用命令npm install react-transition-group --save进行安装。
    该框架包含TransitionCSSTransitionSwitchTransitionTransitionGroup,我们主要使用CSSTransition,官方文档地址:CSSTransition

  2. 组件中引入CSSTransition模块:import { CSSTransition } from 'react-transition-group'

  3. 插件属性配置、 设置样式(.js文件、.css文件)

import React, {Component, Fragment} from 'react';
import { CSSTransition } from 'react-transition-group';
import './style.css'
class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            show: true
        };
        this.handleToggle = this.handleToggle.bind(this);
    }

    render() {
        return (
            <Fragment>
                {/*要使用该框架,需设置
                in 属性:要实现自动在div上增加类名,即通过in的值感知该div是入场状态还是出场状态
                timeout 属性:动画执行时间
                classNames :自定义的class名,注意是classNames
                 unMountOnExit :可选,当动画出场后在页面上移除包裹的dom节点
                 onEnter(onExit):入场(出场)动画第一帧自动执行
                 onEntering(onExiting):入场(出场)动画第二帧自动执行
                 onEntered (onExited):入场(出场)动画完成之后自动执行的钩子,接收一个参数,即插件内部的dom元素
                */}
                <CSSTransition
                    in={this.state.show}
                    timeout={1000}
                    classNames='test'
                    unmountOnExit
                    onEntered={(el)=>{
                        el.style.color='red'
                    }}
                >
                    <div>hello</div>
                </CSSTransition>
                <button onClick={this.handleToggle}>toggle</button>
            </Fragment>
        )
    }

    // 让show不断变换真值
    handleToggle() {
        this.setState({
            show: this.state.show ? false : true
        })
    }
}

export default App;

xxx-enter: 进入(入场)前的CSS样式;
xxx-enter-active:进入动画直到完成时之前的CSS样式;
xxx-enter-done:进入完成时的CSS样式;
xxx-exit:退出(出场)前的CSS样式;
xxx-exit-active:退出动画直到完成时之前的的CSS样式。
xxx-exit-done:退出完成时的CSS样式。

/*test是自定义的类名,插件将会自动的在包裹住的标签上添加很多css样式,默认class名是fade*/

/*enter是入场前的刹那(点击按钮),appear指页面第一次加载前的一刹那(自动)*/
.test-enter, .test-appear {
    opacity: 0;
}
/*enter-active指入场的第二个瞬间到入场结束之前的过程,appear-active则是页面第一次加载自动执行*/
  .test-enter-active, .test-appear-active {
      opacity: 1;
      transition: opacity 1s ease-in;
  }
/*入场动画执行完毕后,用于保持状态*/
  .test-enter-done {
      opacity: 1;
      /*color: red; 也可以用js来实现,即onEntered钩子*/
  }
/*出场前的第一刹那*/
.test-exit {
    opacity: 1;
}

.test-exit-active {
    opacity: 0;
    transition: opacity 1s ease-in;
}
/*入场动画执行完毕后,用于保持状态*/
.test-exit-done {
    opacity: 0;
}

项目地址:单个组件动画

3.多个组件的动画效果

使用TransitionGroup,只需变动js文件

import React, {Component, Fragment} from 'react';
import { CSSTransition,TransitionGroup } from 'react-transition-group';
import './style.css'
class App extends Component {

    constructor(props) {
        super(props);
        this.state = {
            show: true,
            list:[]
        };
        this.handleAddItem = this.handleAddItem.bind(this);
    }

    render() {
        return (
            <Fragment>
                {/*所有组件外层包裹TransitionGroup*/}
                <TransitionGroup>
                        {
                        // 这里注意map的参数第一个item是元素,第二个index是下标,注意顺序
                        this.state.list.map((item,index)=>{
                            return (
                                // 每个组件或元素包裹CSSTransition
                                <CSSTransition
                                    key={index}
                                    timeout={1000}
                                    classNames='test'
                                    unmountOnExit
                                    onEntered={(el)=>{
                                        el.style.color='red'
                                    }}
                                >
                                    <div >{item}</div>
                                </CSSTransition>
                            )
                        })
                        }
                </TransitionGroup>
                <button onClick={this.handleAddItem}>Add</button>
            </Fragment>
        )
    }

    //每点击一次便增加一个item
    handleAddItem(){
        this.setState((prevState)=>{
            return{
                list:[...prevState.list,'item']
            }
        })

    }
}

export default App;

项目地址:多个组件动画

注意:使用styled-components之后引入css文件将失效

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值