KeyFrames.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* eslint-disable react/destructuring-assignment */
  2. import React, { Component, isValidElement } from 'react';
  3. import PropTypes from 'prop-types';
  4. import noop from './utils/noop';
  5. import Animation from './Animation';
  6. export interface KeyFramesProps {
  7. frames?: any[];
  8. loop?: boolean;
  9. forwardInstance?: (value: any) => void;
  10. onFrame?: (value: any) => void;
  11. onKeyRest?: (value: Record<string, any>) => void;
  12. onRest?: (value: Record<string, any>) => void;
  13. }
  14. export interface KeyFramesStates {
  15. currentStyle: Record<string, any>;
  16. frameIndex: number;
  17. }
  18. export default class KeyFrames extends Component<KeyFramesProps, KeyFramesStates> {
  19. static propTypes = {
  20. frames: PropTypes.array,
  21. loop: PropTypes.bool,
  22. onFrame: PropTypes.func,
  23. onKeyRest: PropTypes.func,
  24. onRest: PropTypes.func,
  25. };
  26. static defaultProps = {
  27. frames: [] as any[],
  28. loop: false,
  29. onKeyRest: noop,
  30. onRest: noop,
  31. onFrame: noop,
  32. };
  33. instance: any;
  34. constructor(props = {}) {
  35. super(props);
  36. this.state = {
  37. currentStyle: {},
  38. frameIndex: 0,
  39. };
  40. }
  41. onFrame = (props = {}) => {
  42. const currentStyle = { ...props };
  43. this.props.onFrame(currentStyle);
  44. this.setState({ currentStyle });
  45. };
  46. next = () => {
  47. let { frameIndex } = this.state;
  48. const { frames, loop } = this.props;
  49. frameIndex++;
  50. if (frameIndex < frames.length - 1) {
  51. this.setState({ frameIndex });
  52. } else {
  53. frameIndex = 0;
  54. this.props.onRest(this.state.currentStyle);
  55. if (loop) {
  56. this.setState({ frameIndex });
  57. }
  58. }
  59. this.props.onKeyRest(this.state.currentStyle);
  60. };
  61. forwardInstance = (instance: any) => {
  62. this.instance = instance;
  63. if (typeof this.props.forwardInstance === 'function') {
  64. this.props.forwardInstance(this.instance);
  65. }
  66. };
  67. componentDidMount() {
  68. // this.props.forwardInstance(this.instance);
  69. }
  70. componentWillUnmount() {
  71. this.instance && this.instance.destroy();
  72. }
  73. render() {
  74. const { children, frames } = this.props;
  75. const { frameIndex, currentStyle } = this.state;
  76. const from = frames[frameIndex];
  77. const to = frames[frameIndex + 1];
  78. return (
  79. <Animation
  80. {...this.props}
  81. forwardInstance={this.forwardInstance}
  82. from={from}
  83. to={to}
  84. onFrame={this.onFrame}
  85. onRest={this.next}
  86. >
  87. {typeof children === 'function' ? children(currentStyle) : children}
  88. </Animation>
  89. );
  90. }
  91. }