让React应用“动”起来
WEB应用中动画很重要不管是web应用还是原生应用,也不论是PC端应用还是移动端应用,动画都扮演了一个重要的角色。 尽管动画并不会添加应用的实际动能,但一个好的动画,一个流畅且优雅,选择在恰当时机出现的动画,能为应用增色不少,能很好的引导用户进行下一步操作,让应用的场景切换更合理。一个小小的细节动画,就能几个层次的提升应用的用户体验。 举个简单的例子,应用中最常见的页面间切换,如果缺少切换动画,那就会是这个样子:
非常生硬,页面的出现显得非常突兀。作为对比,我们可以看下添加了动画的页面切换是什么样子的呢:
增加了用户预期,也能较好的提示用户页面的层级关系。 再举个弹窗的例子,先放两个对比图,左边是无动画的效果,右边是添加完动画的效果:
动画虽然没有添加什么实际可见的功能,但是通过对比,不难发现,动画的添加,让弹窗的出现显得平滑自然,让页面的场景替换有一个过程,减少突兀感,让用户体验感受增色不少不是吗? 当然有可能因为录制的问题,动画效果不是很明显,你可能有不同的看法。 动画实现的基本原理web应用的基本骨架是DOM,正是一个个的DOM节点,构建出web应用,换句话说,就是web应用呈现出来的样子是DOM决定的(当然这里把CSS样式,归纳为了DOM的一部分)。所以动画的实现,从本质上来讲,就是操作DOM:让DOM在不同的时间节点,在不同的位置、有不同的大小、透明度、呈现不同的背景色等,并且让这种变化连续起来,则构成了我们能观察到的动画。 基于web动画实现的基本原理,在我们直接操作DOM的时代,实现动画相对我们来说,非常直观——只要知道怎么操作DOM即可。比如需要实现一个黑色背景的div方块,1s内从离左边距100px的位置,移动到离左边距200px的位置,则我们只需要每秒控制该div的 上述动画实现的方式,我们称为JS动画。是由JS脚本逻辑,动态的改变DOM的CSS属性值。 CSS3中,添加了动画的实现的方案,所以web中第二种动画实现,被我们称为 MV*模式下的动画实现这里的MV*模式我们不展开说,特指React中动画的实现。React由于加入了虚拟DOM等诸多特性,并且其开发模式让开发者不需要或者不推荐直接接触到真实的DOM结构。所以其动画实现,与常规的开发方式下的动画实现,存在一定得差异。 动画的实现最终一定是落地到操作DOM,MV*模式的框架则是数据驱动DOM的展示。如果我们因为动画实现的需要,对DOM的操作出现问题,势必会影响到应用的相关操作。我们先不去深入探讨怎么解决这个问题,先看看React官方和社区对这个问题是怎么解决的,让我们能先给我们的React应用添加上需要的动画。 由浅及深,我们先学会怎么使用,再去了解内部的实现原理,从而根据应用自身需求,能实现自定义的动画,能实现更为复杂的交互动画等。 React中我们怎么添加动画React的动画库中,比较常用的是
另一个常用的React动画库是 1. ReactCSSTransitionGroup
我们以 todo-list 为例,看看 index.js: import React,{ Component } from 'react' ; import ReactCSSTranstionGroup from 'react-addons-css-transition-group' ; export default class App extends Component{ ...,render(){ const { items } = this.state ; return ( <div> ...,<div className="list"> <ReactCSSTransitionGroup transitionName="example" transitionEnterTimeout={500} transitionLeaveTimeout={300} component="div" > { items.map((item)=>( <div key={item} className="item">{item}</div> )) } </ReactCSSTransitionGroup> </div> </div> ) } } style.css: .example-enter { opacity: 0.01; } .example-enter.example-enter-active { opacity: 1; transition: opacity 500ms ease-in; } .example-leave { opacity: 1; } .example-leave.example-leave-active { opacity: 0.01; transition: opacity 300ms ease-in; } 有两点需要注意:
关于 2. ReactTransitionGroup
那我们看看,同样以 todo-list 为例, index.js: import React,{ Component } from 'react' ; import ReactTransitionGroup from 'react-addons-transition-group' ; class Item extends Component{ // 获取组件真实DOM getRef(ref){ this.ref=ref ; } componentWillEnter(callback){ this.ref.classList.add('example-enter') ; setTimeout(()=>{ callback() ; },500) ; } componentDidEnter(){ this.ref.classList.add('example-enter-active') ; } componentWillLeave(){ this.ref.classList.remove('example-enter','example-enter-active') ; this.ref.classList.add('example-leave-active','example-leave') ; setTimeout(()=>{ callback() ; },300) ; } render(){ const { text,onRemove } = this.props ; return ( <div ref={this.getRef} onClick={onRemove} className={styles.item}> {text} </div> ) } } export class App extends Component{ ...,<div className="list"> { items.map((item,i)=>( <Item key={item} text={item} ...otherProps /> )) } </div> </div> ) } } style.css: .example-enter { opacity: 0.01; } .example-enter.example-enter-active { opacity: 1; transition: opacity 500ms ease-in; } .example-leave { opacity: 1; } .example-leave.example-leave-active { opacity: 0.01; transition: opacity 300ms ease-in; } 相比于 通常情况下,我们用 3. ReactMotion
跟其他React动画库一样,
仍然是 todo-list 的例子, import React,{ Component } from 'react' ; import { Motion,spring } from 'react-motion'; export default class App extends Component{ ...,render(){ const { items } = this.state ; return ( <div> ...,<div className="list"> { items.map((item)=>{ return ( <Motion defaultStyle={{opacity:0}} style={{opacity:spring(1)}}> { interpolatingStyle => ( <div key={item} className="item" style={interpolatingStyle} > {item} </div> ) } </Motion> ) }) } </div> </div> ) } } 通过上述简单的代码,即可实现每个Item在 另一方面,观察上述实现,我们不难发现, 除了上述简单的动画应用,
这个示例展示了部分 结语当然React动画相关的库还有很多,本文不过多介绍。通过上述对这些库的使用做简单介绍,笔者希望通过对它们实现进行分析,让读者能更好的理解与掌握,能对React动画的实现原理和实现方式,有更为清晰的认识。 但是对相关代码的研究,深入度还不足以给读者朋友分享,所以暂时留坑,后续会将相关源码的学习,记录在文档React动画的实现原理一文中,并计划添加从零开始,实现React动画文章作为学习成果。如果对React动画保有兴趣,可以关注这两篇文章的后续内容。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |