反应动画表现

时间:2019-04-28 18:26:33

标签: reactjs animation svg

在我的React应用中,我正在使用Kute.js进行动画制作。这个问题更特定于React的动画制作方式。

我有两个组成部分,如下所示:

// parent component creates child components
class SVGIllustration extends Component {
  render() {
    const { currentStep, data } = this.props;
    const { stances } = data;
    const { paths } = stances[currentStep];
    return (
      <svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 7000 11000"
      >
        {paths.map((path, i) => (
          <Path d={path.d} pathId={path.pathId} key={i} />
        ))}
      </svg>
    );
  }
}

// Each child component (an SVG Path) upon update 
// (when componentDidUpdate is called), should 
// 'morph' into the new path 'd' value
class Path extends Component {
  constructor(props) {
    super(props);
    const { pathId } = props;
    this[pathId] = React.createRef();
  }

  componentDidUpdate(prevProps) {
    const { d: prevD } = prevProps;
    const { d, pathId } = this.props;
    // The following Kute.js syntax says: 
    // animate element 'this[pathId].current' from
    // previous 'd' value (prevD) to the new 'd' value
    // & apply the properties specified in 3rd object.
    Kute.fromTo(
      this[pathId].current,
      {
        path: prevD,
      },
      {
        path: d,
      },
      {
        duration: 500,
        morphIndex: 117,
        start: () => console.log("start of animation"),
      }
    ).start();
  }

  render() {
    const { d, pathId } = this.props;
    return <path d={d} id={pathId} ref={this[pathId]} />;
  }
}

为完整起见,这里是SVG,每个<Path>都应设置为动画,以通过道具接收到下一个d值。

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 7000 11000" class="svgIllustration">
  <path d="M1870.7 8115c-2.2,-3.9 -54.5,-196.6 -42.8,-55 19.6,55.7 49.8,126.9 79.4,174.6 57.7,93.4 295.6,299.1 191.1,844.7 -172.3,44.7 -232,40.2 -332.5,-7 -301.5,-141.7 -195.1,-291.2 -204.4,-536 -0.4,-10.6 -0.8,-21.2 -2.2,-29.8 -7.8,-48.8 -59.7,-20.6 -69,5.9 4.1,59.5 8.5,137 8,183.4 -2.1,222.4 -25.5,247.6 154.9,388.6 125,88.1 241.1,110.6 367.4,67.6 272.2,-80 10.8,-247.2 -76,-369.6 0.1,0 -86.1,-141.8 -94.9,-147.4z" id="rgtFoot"></path>
  <path d="M1979.6 8758.7c94.5,-26.2 263.8,-86.8 367.6,-75 -12.1,-26.1 -12.3,-35.3 -9.4,-63.6 0.6,-5.4 0.4,-6.2 -0.6,-5.8 -36.8,22.6 -98.4,36.9 -169.3,54 -77.3,18.7 -165.3,40.5 -215.7,51.6 9.1,13 18.1,26 27.4,38.8z" id="betweenFeetPrayerMat"></path>
  <path d="M2451.9 8749c54.9,19.4 121.4,27.1 168.7,43.1 211.2,71.7 288.8,165.8 524.3,69.8 33.3,-13.6 56.2,-28.4 74.1,-44.1 17.9,-15.7 30.9,-32.2 34.4,-48.2 3.5,-15.9 -2.6,-31.3 -15.7,-51.6 -97.5,-150.2 -331.4,-96.9 -448.1,-334.7 -80.6,-153.8 -21,119.9 170.8,210.4 112.3,53 443.6,166 96.8,247.3 -197.3,46.2 -214.7,-23.4 -382.1,-86.8 -64.2,-24.3 -265.5,-55.6 -257.8,-143 7.6,-84.2 43.4,-183 56.5,-271.2 0.6,-4.7 1.1,-9.4 -8.3,-10.3 -11,-1.1 -61,4.4 -70,10.5 -5.7,3.9 -9.1,10.6 -10.9,16.7 -4.1,13.6 -3.6,41.8 -5.2,57.4 -12.8,126.1 -86.6,268.4 72.5,334.7z" id="lftFoot"></path>
  <path d="M2275.3 753.5c180.2,-55.4 489.4,-93.3 650.4,8.1 6.3,3.9 74.6,50.8 71.1,41 -164.4,-196.4 -484.9,-110.8 -693.8,-112.2 -62.1,-0.3 -71.9,-15.5 -83.1,-53.3 -11.3,-37.9 -21.1,-83.4 -7.4,-114.3 59.2,-131.1 741.2,-205.1 743.3,61.3 0,9.9 0,30.2 3.5,21.4 70.1,-187.9 -182.3,-230 -318,-240.5 -219.5,-12.3 -512.6,42.1 -685.8,187.2 -16.1,13.4 -16.1,13.4 -3.5,71.9l49.1 234.9c2.2,11.2 4.2,22.8 7,33.6 49.8,-49.1 200.9,-118.8 267.2,-139.1l0 0z" id="cap"></path>
  <path d="M2162.7 912c3.3,-29.8 9.8,-59.2 19.4,-87.6 1.4,-4.9 1,-8.4 -6.7,-7 -30.8,7 -170.7,90.4 -185.8,122 -3,7.3 -5.2,15.1 -6.3,23 -48.1,330 409.4,983.2 736.6,763.7 103,-69.4 243.6,-468.1 245.4,-570.1 2.4,-98.2 -4.2,-110.5 8.4,-218.1 2.8,-23.9 0.7,-155.3 -10.2,-136.7 -4.5,8 -8,111.5 -11.5,133.2 -18.6,110.1 -11.6,120.6 -17.2,220.9 -4.9,91.8 -128.3,408.8 -203,478.9 -233.6,219.8 -516.8,-236.3 -558.2,-452.3 -10.2,-56.7 -15.4,-114.6 -15.4,-172.2 0,-32.5 1.7,-65.4 4.9,-97.7l-0.4 0z" id="face"></path>
  <path d="M2120.3 1468.4c-7,-10.5 -73,-119.2 -75.4,-116 -1.8,2.1 -2.2,11.5 -2.2,21.7 -1.4,289.9 -63.8,471.2 182.7,687.9 22.4,19.3 108.7,94.7 129.7,101.3 7,2.1 20.3,6.3 5.7,-10.5 -147.3,-166.6 -278.4,-363.9 -209.3,-596.8 5.9,-35.7 -12.7,-58.2 -31.6,-87.6l0.4 0z" id="neck"></path>
  <path d="M2634.3 1921.4c-19.3,83.8 -138.9,280.5 -71.9,208.2 29.1,-33.3 59.3,-66.6 85.9,-102.3 67.7,-89.8 73,-118.9 196.4,-101 117.8,17.5 269.6,96.7 363.6,173.2 240.8,195.6 273.5,830.6 291,1121.6 25.6,427.3 43.8,994.7 13,1422.4 -18.3,249.3 -117.5,119.9 -184.8,178.4 -14,11.9 72.2,14.1 84.5,18.3 17.6,6.3 18.6,17.5 18.3,33.6 12.3,155 108.7,455.1 26.6,586.2 -65.9,104.9 -186.8,38.6 -148.7,74 51.6,47.7 152.2,16.5 191.8,-34 70.1,-89.4 12.3,-361.1 1.7,-488 -4.9,-65.6 -4.9,-127.3 -6.3,-192.5 136,-71.2 83.5,-1321.4 75,-1515.3 -11.5,-264 -46.3,-508.4 -73.2,-697.7 -73.6,-518.3 -159.9,-569.4 -660.9,-779.8 -177.4,-74.3 -164.8,-65.6 -202,94.7z" id="lftShoulder"></path>
  <path d="M2042.1 1903.5c7,-11.9 6.4,-35.1 -1.4,-61.4 -7.7,-26.6 -22.1,-57.2 -48.4,-68.4 -92.9,-39.2 -576.7,149.8 -717,238.1 -253.1,159.5 -301.5,433.4 -333.1,712.4 -63.1,571.6 -41.7,1385 32.6,1952.9 21.1,160.2 40.3,239.1 50.2,278.4 9.4,39.6 9.4,39.6 -2.8,-33.3 -25.7,-148.9 -43.6,-300.8 -52.8,-451.7 -15.1,-232.4 -21,-551.5 -17.2,-844.3 6,-413.4 -13,-1319.3 408.5,-1552.5 178.8,-98.8 420,-151.8 622,-156.3 36.8,-0.7 51.8,-1.8 59.2,-13.7l0.2 -0.2z'/>" id="rgtShoulder"></path>
  <path d="M1619.3 3200.4c41.4,-208.7 64.2,-466.3 123.8,-663.7 84.8,-280.5 -56.8,19.3 -80.3,119.2 -201.3,850.6 -258.7,1180.5 -193.2,2050 9.1,123.4 15.8,182.3 13,210.4 -2.8,28.1 -15.1,25.9 -50.5,24.5 -58.2,-1.7 -482.8,40 -441.8,67.3 1.1,0.7 453,-18.9 503.1,-18.5 40.3,0.3 40.3,-0.4 37.9,-64.9 -22.1,-597.1 -29.1,-1131.4 88,-1724.3l0 0z" id="rgtShoulderInspathIde"></path>
  <path d="M3134.3 3037.3c87.6,1528.3 37.8,2852.2 3.5,4368.6 -48.8,2199.3 150.7,-1820.7 163,-2170.2 5.6,-331 -14,-745.4 -16.1,-957.9 -3.5,-393.8 -246.1,-2909 -150.4,-1240.5z" id="lftShoulderInspathIde"></path>
  <path d="M1218.5 5015.8c-5.2,-11.2 -69,-7 -76,4.2 -3.5,5.3 -6,15.1 -8.1,24.6 -10.7,46 -23.3,93.3 -35.9,138.8 -35,122.7 -109.7,544.1 100.3,555.6 72.5,3.5 138.5,-73.6 168.3,-132.1 31.5,-63.8 22.1,-128.3 78.5,-78.9 152.2,133.9 -16.1,-436.5 -19.7,-452.3 -19.2,-86.2 -15.4,-18.5 -8.8,20.4 7,39.2 23.2,94.6 35.8,150 11.8,50.4 20,102.1 24.4,153.6 12.3,184.8 -62.8,-18.2 -114,75 -14,25.6 -32.2,74.3 -56.1,114 -147.2,246.4 -206.1,-21.8 -199.5,-154.3 5.7,-102.4 124.1,-388.1 110.8,-418.2l0 -0.4z" id="rgtHand"></path>
  <path d="M3280.5 8405.5c-36.5,9.4 -264.4,70.1 -287.5,84.5 -112.2,68.4 338.7,-49.1 413.7,-54.7 117.4,-9.1 220.9,44.5 322.9,92.9 914.8,427.8 1944.2,850.2 2910.4,1144 -689.3,235.3 -1396.8,514 -2083.3,769.3 -580,215.3 -1427.4,559.9 -203,126.2 828.4,-293.8 1655.2,-579.5 2474.1,-900 294.6,-118.5 16.5,-61.7 -117.4,-18.9 -204.1,-81.7 -589,-219.9 -931.2,-345.4 -708.2,-259.5 -1341.1,-527.3 -2027.6,-834.4 -226.1,-101.4 -283.3,-112.6 -471.2,-63.9l0.1 0.4z" id="lftPrayerMat"></path>
  <path d="M1461.8 8864.1c0,-9.9 1.8,-20.3 2.8,-31.2 -82.7,16.8 -671.7,124.8 -699.8,151.8 -70.1,68 2226.4,1428.4 2453.6,1588.2 130.7,91.9 316.2,235.7 465.6,285.8 16.8,5.6 21,7 9.4,-2.1 -61.6,-45.7 -126.2,-93.4 -186.6,-139.8 -809.6,-617.1 -1737.3,-1004.5 -2506.9,-1612.1 -110.4,-87.7 -99.6,-115.7 47,-140.2 140.2,-22.5 277.7,-47 417.2,-73.6 -1.4,-8.8 -2.5,-17.6 -2.1,-27l-0.2 0.2z" id="rgtPrayerMat"></path>
  <path d="M1371.4 8462.3c599.2,-92.2 1204,-182.3 1807.4,-236.3 69.1,-6.3 96.7,-7 75.4,-10.5 -285,-50.2 -1196.3,56 -1522.7,91.1 -392,41 -479.3,28.1 -487,-370.5 -2.8,-145.9 -11.9,-300.2 -16.8,-531.6 -3.2,-158.8 8.1,-1585.1 6.3,-1589.7 -100.2,-276.9 -127.6,1024.9 -128,1037.5 -10.5,476.8 -39.2,1040.6 10.6,1509.7 13,122.7 31.2,128.3 65.9,126.2 35,-1.4 86.9,-10.5 189.3,-26.3l-0.4 0.4z" id="dress"></path>
</svg>

SVG很大,但没有那么大,所以我很惊讶动画的速度(浏览器实际上警告等待或停止页面脚本)。我是在使用正确的React Lifecycle方法和/还是在这里缺少技巧?

谢谢

编辑: 我能想到的最好的办法是摆弄动画精度的值(morphIndex属性)和使用if条件来比较componentDidUpdate中的prev和当前prop值,这有所帮助,不足以使其在移动设备上流畅运行。

0 个答案:

没有答案