当前位置:Gxlcms > JavaScript > 在React中写一个Animation组件为组件进入和离开加上动画/过度效果

在React中写一个Animation组件为组件进入和离开加上动画/过度效果

时间:2021-07-01 10:21:17 帮助过:16人阅读

问题

在单页面应用中,我们经常需要给路由的切换或者元素的挂载和卸载加上过渡效果,为这么一个小功能引入第三方框架,实在有点小纠结。不如自己封装。

思路

原理

以进入时 opacity: 0 --> opacity: 1  ,退出时 opacity: 0 --> opacity: 1 为例

元素挂载时

1.挂载元素dom
2.设置动画 opacity: 0 --> opacity: 1

元素卸载时

1.设置动画 opacity: 0 --> opacity: 1
2.动画结束后卸载dom

组件设计

为了使得组件简单易用、低耦合,我们期望如下方式来调用组件:

属性名 类型 描述
isShow Boolean 子元素显示或隐藏控制
name String 指定一个name,动画进入退出时的动画

在 App.jsx 里调用组件:

通过改变isShow的值来指定是否显示

  1. // App.jsx
  2. // 其他代码省略
  3. import './app.css';
  4. <Animation isShow={isShow} name='demo'>
  5. <div class='demo'>
  6. demo
  7. </div>
  8. </Animation>
  9. // 通过改变isShow的值来指定是否显示
  10. 在 App.css 里指定进入离开效果:
  11. // 基础样式
  12. .demo {
  13. width: 200px;
  14. height: 200px;
  15. background-color: red;
  16. }
  17. // 定义进出入动画
  18. .demo-showing {
  19. animation: show 0.5s forwards;
  20. }
  21. .demo-fading {
  22. animation: fade 0.5s forwards;
  23. }
  24. // 定义动画fade与show
  25. @keyframes show {
  26. from {
  27. opacity: 0;
  28. }
  29. to {
  30. opacity: 1;
  31. }
  32. }
  33. @keyframes fade {
  34. from {
  35. opacity: 1;
  36. }
  37. to {
  38. opacity: 0;
  39. }
  40. }

根据思路写代码

  1. // Animation.jsx
  2. import { PureComponent } from 'react';
  3. import './index.css';
  4. class Animation extends PureComponent {
  5. constructor(props) {
  6. super(props);
  7. this.state = {
  8. isInnerShow: false,
  9. animationClass: '',
  10. };
  11. }
  12. componentWillReceiveProps(props) {
  13. const { isShow } = props;
  14. if (isShow) {
  15. // 显示
  16. this.show().then(() => {
  17. this.doShowAnimation();
  18. });
  19. } else {
  20. // 隐藏
  21. this.doFadeAnimation();
  22. }
  23. }
  24. handleAnimationEnd() {
  25. const isFading = this.state.animationClass === this.className('fading');
  26. if (isFading) {
  27. this.hide();
  28. }
  29. }
  30. show() {
  31. return new Promise(resolve => {
  32. this.setState(
  33. {
  34. isInnerShow: true,
  35. },
  36. () => {
  37. resolve();
  38. }
  39. );
  40. });
  41. }
  42. hide() {
  43. this.setState({
  44. isInnerShow: false,
  45. });
  46. }
  47. doShowAnimation() {
  48. this.setState({
  49. animationClass: this.className('showing'),
  50. });
  51. }
  52. doFadeAnimation() {
  53. this.setState({
  54. animationClass: this.className('fading'),
  55. });
  56. }
  57. /**
  58. * 获取className
  59. * @param {string} inner 'showing' | 'fading'
  60. */
  61. className(inner) {
  62. const { name } = this.props;
  63. if (!name) throw new Error('animation name must be assigned');
  64. return `${name}-${inner}`;
  65. }
  66. render() {
  67. let { children } = this.props;
  68. children = React.Children.only(children);
  69. const { isInnerShow, animationClass } = this.state;
  70. const element = {
  71. ...children,
  72. props: {
  73. ...children.props,
  74. className: `${children.props.className} ${animationClass}`,
  75. onAnimationEnd: this.handleAnimationEnd.bind(this),
  76. },
  77. };
  78. return isInnerShow && element;
  79. }
  80. }
  81. export default Animation;

Demo示例

点我直达

总结

以上所述是小编给大家介绍的在React中写一个Animation组件为组件进入和离开加上动画/过度效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

人气教程排行