为什么cancelAnimationFrame () 不会在MouseDown 事件上停止动画?

问题描述

为什么 cancelAnimationFrame () 不会在 MouseDown 事件 上停止动画?但是第二次点击会触发动画停止。可能是什么问题呢?有没有办法,在过早停止动画后,返回当前的“cur”和“rez " 来自“动画函数”的值?

完整版的代码。 https://codesandbox.io/s/peaceful-silence-bm6hx?file=/src/scroll.js

const Scrollable = (props) => {
  const items = props.items;

  let ref = useRef();
  let refAnimation = useRef();

  const [state,setState] = useState({
    isScrolling: false,clientX: 0,//Position of the mouse on the object
    scrollX: 0 //Position of the propelled object
  });
  const [touchStart,setTouchStart] = useState(0);

  const onMouseDown = (e) => {
    if (ref && ref.current && !ref.current.contains(e.target)) {
      return;
    }
    e.preventDefault();
    ///////////////-----------------////////////////
    cancelAnimationFrame(refAnimation.current);
    //////////////------------------///////////////
  };

  /////////Mouse Move Event///////////
  const onMouseMove = (e) => {
    if (ref && ref.current && !ref.current.contains(e.target)) {
      return;
    }
    e.preventDefault();
    

    if (isScrolling === true) {
      let sX = scrollX - e.clientX + clientX;
      let cX = e.clientX;


        ref.current.scrollLeft = scrollX - e.clientX + clientX;
        setState({
          ...state,scrollX: sX,clientX: cX
        });
    }
  };

  /////Mouse UP Event/////
  const onMouseUp = (e) => {
    if (ref && ref.current && !ref.current.contains(e.target)) {
      return;
    }
    e.preventDefault();

    let touchShift = touchStart - state.clientX;
    let rez;
    let shift;


    if (touchShift < 0) {
      shift = 300 + touchShift;
      rez = state.scrollX - shift;
      let speed = shift / 400;
      let cur = state.scrollX;

      if (rez <= -300) {
        setState({
          ...state,isScrolling: false
        });
      } else {
        refAnimation.current = requestAnimationFrame(() =>
          animate(cur,speed,rez,"left")
        );
      }
    }

    if (touchShift > 0) {
      ...
    }

    if (touchShift === 0) {
      setState({
        ...state,isScrolling: false
      });
    }
  };

  //////A callable function that should do the animation
  const animate = (cur,dir = "left",callback) => {
    refAnimation.current = requestAnimationFrame(() =>
      animate(cur,dir)
    );
    cur = dir === "left" ? cur - speed : cur + speed;
    ref.current.scrollLeft = cur.toFixed(2);
    
    if (Math.round(cur) === rez) {
      cancelAnimationFrame(refAnimation.current);
      setState({
        ...state,scrollX: rez,isScrolling: false
      });
    }
  };

  /////////////////////////////////////////

  useEffect(() => {
    document.addEventListener("mousedown",onMouseDown);
    document.addEventListener("mouseup",onMouseUp);
    document.addEventListener("mousemove",onMouseMove);
    return () => {
      document.removeEventListener("mousedown",onMouseDown);
      document.removeEventListener("mouseup",onMouseUp);
      document.removeEventListener("mousemove",onMouseMove);
    };
  });
  useEffect(() => {
    if (ref.current === true) {
      refAnimation.current = requestAnimationFrame(() => animate(0,0));
    }
    return () => {
      cancelAnimationFrame(refAnimation.current);
    };
  },[]);


  return (
    <div className={classes.charPage}>
      <div
        className={classes.items}
        ref={ref}
        onMouseDown={onMouseDown}
        onMouseUp={onMouseUp}
        onMouseMove={onMouseMove}
      >
      </div>
    </div>
  );
};

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)