CSSTransitionGroup
实现动画的优点是:
- 简单易用,可以方便快捷地实现元素的入场和离场动画;
- 与 React 结合,性能比较好。
CSSTransitionGroup
缺点也十分明显:
- 局限于出现动画,入场动画和离场动画;
- 由于需要制定
transitionName
,灵活性不够; - 只能依靠 css 实现简单的动画。
四、结合 hook 实现复杂动画
在实际项目中,可能需要一些更炫酷的动画效果,这些效果仅依赖于 css3 往往较难实现。此时,我们不妨借助一些成熟的第三方库,如 jQuery 或 GASP,结合 React 组件中的生命周期钩子方法 hook 函数,实现复杂动画效果。除了 React 组件正常的生命周期外, CSSTransitionGroup
的底层 api TransitonGroup
还为其子元素额外提供了一系列特殊的生命周期 hook 函数,在这些 hook 函数中结合第三方动画库可以实现丰富的入场、离场动画效果。
TransisitonGroup
分别提供一下六个生命周期 hook 函数:
- componentWillAppear(callback)
- componentDidAppear()
- componentWillEnter(callback)
- componentDidEnter()
- componentWillLeave(callback)
- componentDidLeave()
它们的触发时机如图所示:
示例
GASP 是一个 flash 时代发展至今的动画库,借鉴视频帧的概念,特别适合做长时间的序列动画效果。本文中,我们用 TransitonGroup
和 react-gsap-enhancer
(一个可以将 GSAP 应用于 React 的增强库)完成一个图片画廊,代码如下:
import React, { Component } from 'react'; import { TransitionGroup } from 'react-transition-group'; import GSAP from 'react-gsap-enhancer' import { TimelineMax, Back, Sine } from 'gsap'; class Photo extends Component { constructor(props) { super(props); } componentWillEnter(callback) { this.addAnimation(this.enterAnim, {callback: callback}) } componentWillLeave(callback) { this.addAnimation(this.leaveAnim, {callback: callback}) } enterAnim = (utils) => { const { id } = this.props; return new TimelineMax() .from(utils.target, 1, { x: `+=${( 4 - id ) * 60}px`, autoAlpha: 0, onComplete: utils.options.callback, }, id * 0.7); } leaveAnim = (utils) => { const { id } = this.props; return new TimelineMax() .to(utils.target, 0.5, { scale: 0, ease: Sine.easeOut, onComplete: utils.options.callback, }, (4 - id) * 0.7); } render() { const { url } = this.props; return ( <div className="photo"> <img src={url} /> </div> ) } } const WrappedPhoto = GSAP()(Photo); export default class Gallery extends Component { constructor(props) { super(props); this.state = { show: false, photos: [{ id: 1, url: 'http://img4.imgtn.bdimg.com/it/u=1032683424,3204785822&fm=214&gp=0.jpg' }, { id: 2, url: 'http://imgtu.5011.net/uploads/content/20170323/7488001490262119.jpg' }, { id: 3, url: 'http://tupian.enterdesk.com/2014/lxy/2014/12/03/18/10.jpg' }, { id: 4, url: 'http://img4.imgtn.bdimg.com/it/u=360498760,1598118672&fm=27&gp=0.jpg' }] }; } toggle = () => { this.setState({ show: !this.state.show }) } render() { const { show, photos } = this.state; const renderPhotos = () => { return photos.map((item, index) => { return <WrappedPhoto id={item.id} url={item.url} key={`photo${item.id}`} />; }) } return ( <div> <button onClick={this.toggle}>toggle</button> <TransitionGroup component="div"> {show && renderPhotos()} </TransitionGroup> </div> ); } }
内容版权声明:除非注明,否则皆为本站原创文章。