index.jsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import React from 'react';
  2. import { Animation, interpolate } from '@douyinfe/semi-animation-react';
  3. const styles = {
  4. container: {
  5. height: '100%',
  6. display: 'flex',
  7. justifyContent: 'center',
  8. alignItems: 'center',
  9. willChange: 'background',
  10. },
  11. shape: { width: 300, height: 300, willChange: 'transform' },
  12. };
  13. export default class SimpleAnimation extends React.Component {
  14. state = { toggle: true };
  15. toggle = () => {
  16. this.setState(state => ({ toggle: !state.toggle }));
  17. if (this.handler && this.handler.reverse) {
  18. this.handler.reverse();
  19. this.handler.start();
  20. }
  21. };
  22. render() {
  23. const shapeFrom = [20, 380, 380, 380, 380, 380, 200, 20, 20, 380];
  24. const shapeTo = [20, 20, 20, 380, 380, 380, 380, 20, 20, 20];
  25. const prefixes = ['M', ',', ' L', ',', ' L', ',', ' L', ',', ' L', ','];
  26. return (
  27. <Animation
  28. from={{ value: 0 }}
  29. to={{ value: 50 }}
  30. forwardInstance={handler => (this.handler = handler)}
  31. onRest={() => {
  32. if (this.handler) {
  33. this.handler.reverse();
  34. this.handler.start();
  35. }
  36. }}
  37. // to={{
  38. // coords: toggle ? [0, 0] : [50, 50],
  39. // color: toggle ? '#247BA0' : '#70C1B3',
  40. // start: toggle ? '#B2DBBF' : '#B2DBBF',
  41. // end: toggle ? '#247BA0' : '#F3FFBD',
  42. // scale: toggle ? 0.3 : 0.4,
  43. // shape: toggle ? TRIANGLE : RECTANGLE,
  44. // stop: toggle ? '0%' : '50%',
  45. // rotation: toggle ? '0deg' : '45deg',
  46. // }}
  47. >
  48. {({ value }) => {
  49. const ratio = value / 50;
  50. // hsl(48, 16%, 57%) => hsl(71, 100%, 87%)
  51. const start = `hsl(${(71 - 48) * ratio + 48}, ${(100 - 16) * ratio + 16}%, ${(87 - 57) * ratio +
  52. 57}%)`;
  53. const stop = `${value}%`;
  54. const end = `hsl(${value * 5 + 50}, 90%, 60%)`;
  55. // hsl(170, 40%, 60%) => hsl(198, 63%, 38%)
  56. // const color = `hsl(${value * 6 + 40}, 90%, 60%)`;
  57. const color = `hsl(${(198 - 170) * ratio + 170}, ${(63 - 40) * ratio + 40}%, ${(38 - 60) * ratio +
  58. 60}%)`;
  59. const scale = 0.1 * ratio + 0.3;
  60. const rotation = 45 * ratio + 'deg';
  61. const coords = [value, value];
  62. const shape = interpolate(shapeFrom, shapeTo, ratio)
  63. .map((v, idx) => '' + (prefixes[idx] || '') + v)
  64. .join('') + ' Z';
  65. return (
  66. <div
  67. style={{
  68. ...styles.container,
  69. // background: `linear-gradient(to bottom, ${start} ${stop}, ${end} 100%)`,
  70. background: `${start}`,
  71. }}
  72. >
  73. <svg
  74. style={{
  75. ...styles.shape,
  76. transform: `scale3d(${scale}, ${scale}, ${scale}) rotate(${rotation}) translate3d(${
  77. coords[0]
  78. }px,${coords[1]}px,0)`,
  79. }}
  80. version="1.1"
  81. viewBox="0 0 400 400"
  82. >
  83. <g style={{ cursor: 'pointer' }} fill={color} fillRule="evenodd" onClick={this.toggle}>
  84. <path id="path-1" d={shape} />
  85. </g>
  86. </svg>
  87. </div>
  88. );
  89. }}
  90. </Animation>
  91. );
  92. }
  93. }