title: Why cancelAnimationFrame () doesn't stop animation on MouseDown event?
body: <p>Why <strong>cancelAnimationFrame ()</strong> doesn't stop animation on <strong>MouseDown event</strong>? But animation stops triggered by a second <strong>click</strong>. What could be the problem?  And is there a way, after premature stopping the <strong>animation</strong>, to <strong>return</strong> the current &quot;<strong>cur</strong>&quot; and &quot;<strong>rez</strong>&quot; values from the &quot;<strong>animate function</strong>&quot;?</p>
  <p>Full version of the code.  <a href="https://codesandbox.io/s/peaceful-silence-bm6hx?file=/src/scroll.js" rel="nofollow noreferrer">https://codesandbox.io/s/peaceful-silence-bm6hx?file=/src/scroll.js</a></p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const Scrollable = (props) =&gt; {
    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) =&gt; {
      if (ref &amp;&amp; ref.current &amp;&amp; !ref.current.contains(e.target)) {
        return;
      }
      e.preventDefault();
      ///////////////-----------------////////////////
      cancelAnimationFrame(refAnimation.current);
      //////////////------------------///////////////
    };
  
    /////////Mouse Move Event///////////
    const onMouseMove = (e) =&gt; {
      if (ref &amp;&amp; ref.current &amp;&amp; !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) =&gt; {
      if (ref &amp;&amp; ref.current &amp;&amp; !ref.current.contains(e.target)) {
        return;
      }
      e.preventDefault();
  
      let touchShift = touchStart - state.clientX;
      let rez;
      let shift;
  
  
      if (touchShift &lt; 0) {
        shift = 300 + touchShift;
        rez = state.scrollX - shift;
        let speed = shift / 400;
        let cur = state.scrollX;
  
        if (rez &lt;= -300) {
          setState({
            ...state,
            isScrolling: false
          });
        } else {
          refAnimation.current = requestAnimationFrame(() =&gt;
            animate(cur, speed, rez, "left")
          );
        }
      }
  
      if (touchShift &gt; 0) {
        ...
      }
  
      if (touchShift === 0) {
        setState({
          ...state,
          isScrolling: false
        });
      }
    };
  
    //////A callable function that should do the animation
    const animate = (cur, speed, rez, dir = "left", callback) =&gt; {
      refAnimation.current = requestAnimationFrame(() =&gt;
        animate(cur, speed, rez, 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(() =&gt; {
      document.addEventListener("mousedown", onMouseDown);
      document.addEventListener("mouseup", onMouseUp);
      document.addEventListener("mousemove", onMouseMove);
      return () =&gt; {
        document.removeEventListener("mousedown", onMouseDown);
        document.removeEventListener("mouseup", onMouseUp);
        document.removeEventListener("mousemove", onMouseMove);
      };
    });
    useEffect(() =&gt; {
      if (ref.current === true) {
        refAnimation.current = requestAnimationFrame(() =&gt; animate(0, 0, 0));
      }
      return () =&gt; {
        cancelAnimationFrame(refAnimation.current);
      };
    }, []);
  
  
    return (
      &lt;div className={classes.charPage}&gt;
        &lt;div
          className={classes.items}
          ref={ref}
          onMouseDown={onMouseDown}
          onMouseUp={onMouseUp}
          onMouseMove={onMouseMove}
        &gt;
        &lt;/div&gt;
      &lt;/div&gt;
    );
  };</code></pre>
  </div>
  </div>
  </p>