按下按钮时开始播放动画

时间:2020-05-09 13:55:30

标签: css reactjs

我正在使用CSS运动路径。

按下按钮时,正方形将开始在路径上移动。

每当我按下按钮时,我都试图使其正常工作,但到目前为止没有成功。

import React, { useState } from "react";
import styled from "styled-components";
import "./App.css";

const PathStyled = styled.div`
  width: 50px;
  height: 50px;
  border: 1px solid hsl(343, 100%, 58%, 0.3);
  border-right: 5px solid hsl(343, 100%, 58%);
  background: hsla(343, 100%, 58%, 0.3)
    radial-gradient(
      circle,
      hsl(343, 100%, 58%, 1) 3px,
      hsl(343, 100%, 58%, 0) 3px
    );
  offset-path: ${(props) => {
    const pathStr = "path('M40,100 l" + props.x + ",0')";
    console.log(pathStr);
    return pathStr;
  }};
  animation: distance 4000ms ease-in-out;
`;

function App() {
  const PATH_X_SEG = 200;
  const PATH_Y_SEG = 0;
  // const offSetPath
  const [path, setPath] = useState({ x: 200, y: 0 });
  const [isStartAnime,setIsStartAnime] = useState(false);
  const addToSVG = () => {
    setPath({ x: path.x + PATH_X_SEG, y: path.y + PATH_Y_SEG });
  };

  const startAnimation = () => {
    // if(isStartAnime) setIsStartAnime(false) doesn't work
    setIsStartAnime(true);
  };

  return (
    <div className="App">
      <div className="controls">
        <button onClick={addToSVG}>Add segment to SVG</button>
        <button onClick={startAnimation}>Start</button>
      </div>
      <br />
      <div className="section-style">
        <svg viewBox="0 0 700 700">
          <path
            d={`M40,100 l${path.x},${path.y}`}
            fill="none"
            stroke="lightgrey"
          />
        </svg>

        {isStartAnime ? <PathStyled x={path.x} y={path.y} /> : ''}
      </div>
    </div>
  );
}

export default App;

Example of how it looks and does

每次按下该怎么办?

1 个答案:

答案 0 :(得分:0)

在这种情况下,您需要删除svg并重新渲染。

您禁用的行不起作用,因为设置状态“ isStartAnime”的方式太快了。在这两行之间,React没有时间在没有svg的情况下渲染组件,并以全新的svg再次渲染它。这就是为什么它不起作用。

相反,您可以检查以下代码:

  const [isStartAnime, setIsStartAnime] = useState(false);
  const [reset, setReset] = useState(false);

  const startAnimation = () => {
    setIsStartAnime(false);
    setReset(true);
  };

  React.useEffect(() => {
    if (!isStartAnime && reset) setIsStartAnime(true);
  }, [isStartAnime, reset]);

  return (
    ...
  );