首页 > 解决方案 > 随着位置的变化平滑地为 div 设置动画

问题描述

我有一个绝对定位的 div:

class MyDiv extends React.Component {
  state = {
    stepCount: 0
  };

  componentDidMount(){
    setInterval(() => {
      this.setState({ stepCount: this.state.stepCount + 1 })
    }, 1000);
  }

  render(){
    return (<div style={{ left: this.state.stepCount * 10 + "%" }} />);
  }
}

CSS
div { transition: 1s linear; }

每秒,我将 div 左移 10%。我希望过渡看起来平滑,但有轻微的口吃。

示例: https ://codepen.io/anon/pen/QoNGbQ

标签: reactjscss-transitions

解决方案


您可能最好使用 CSS 转换或 react-spring 等模块,但如果它们都不适合您,那么您需要requestAnimationFrame.

(CSS 变换可以使文本模糊CSS 过渡效果使图像模糊/移动图像 1px,在 Chrome 中?一次性你可能不希望外部模块的捆绑加载)

https://codesandbox.io/s/pj9m554nkj

const animate = ({ timing, draw, duration }) => {
  let start = performance.now();

  const animateLoop = time => {
    const durationFraction = Math.min(
      1,
      Math.max(0, (time - start) / duration)
    );
    const progress = timing(durationFraction);
    draw(progress);
    if (durationFraction < 1) {
      requestAnimationFrame(animateLoop);
    }
  };

  requestAnimationFrame(animateLoop);
};

const MovingDiv = ({ move, duration }) => {
  const [pos, setPos] = useState(0);
  useEffect(() => {
    animate({
      timing: fraction => move * fraction,
      draw: progress => setPos(progress),
      duration
    });
  }, []);

  return <div className="MovingDiv" style={{ left: pos }} />;
};

然后您也可以开始在计时功能中使用 easeIn/easeOut 来添加一些弹簧。https://codesandbox.io/s/2w6ww8oymp


推荐阅读