G
G
glhit2021-06-21 18:35:52
JavaScript
glhit, 2021-06-21 18:35:52

How to stop the script when hovering over an element (requestAnimationFrame)?

<div style="width: 300px;background-color: black;color: ivory;">

        <style>
            .marquee {
          overflow: hidden;
          font-size: 0;
          font-family: sans-serif;
          text-transform: uppercase;
          white-space: nowrap;
          cursor: default;
          user-select: none;
        }
        
        .marquee__inner {
          font-size: 2rem;
          white-space: nowrap;
          display: inline-block;
        }
        </style>
        <div id="marquee1" class="marquee">
            <div class="marquee__inner">Lorem ipsum dolor sit amet, <strong>consectetur adipisicing elit.</strong>&nbsp;</div>
          </div>
          

        </div>
    <script>
        function animateMarquee(el, duration) {
          const innerEl = el.querySelector('.marquee__inner');
          const innerWidth = innerEl.offsetWidth;
          const cloneEl = innerEl.cloneNode(true);
          el.appendChild(cloneEl);
          
          let start = performance.now();
          let progress;
          let translateX;
          requestAnimationFrame(function step(now) {
                progress = (now - start) / duration;
                if (progress > 1) {
                    progress %= 1;
                    start = now;
                }
                translateX = innerWidth * progress;
                
                innerEl.style.transform = `translate3d(-${translateX}px, 0 , 0)`;
                cloneEl.style.transform = `translate3d(-${translateX}px, 0 , 0)`;
                requestAnimationFrame(step);
                
            });
        }
        
        const marquee1 = document.querySelector('#marquee1');
        
        animateMarquee(marquee1, 15000);
        
    </script>

There is such a code, you need to make it so that when you hover over this element, the scrolling stops. And with the reverse action, the animation resumed from the same place where it stopped. I don't know how to do it. I've tried many things but nothing works well.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
RAX7, 2021-06-21
@glhit

function animateMarquee(el, duration) {
  const innerEl = el.querySelector('.marquee__inner');
  const innerWidth = innerEl.offsetWidth;
  const cloneEl = innerEl.cloneNode(true);
  el.appendChild(cloneEl);

  let start = 0;
  let rafId = null;
  let progressElapsed = 0;
  let progress = 0;

  function step(now) {
    progress = progressElapsed + (now - start) % duration / duration;
    const translateX = innerWidth * progress;

    innerEl.style.transform = `translate3d(-${translateX}px, 0 , 0)`;
    cloneEl.style.transform = `translate3d(-${translateX}px, 0 , 0)`;
    rafId = requestAnimationFrame(step);
  }
  
  function play() {
    if (rafId) return;
    progressElapsed = progress;
    start = performance.now();
    rafId = requestAnimationFrame(step);
  }
  
  function pause() {
    cancelAnimationFrame(rafId);
    rafId = null;
  }

  play();
  return { play, pause };
}

const marquee1 = document.querySelector('#marquee1');
const playback = animateMarquee(marquee1, 15000);

marquee1.addEventListener('mouseenter', () => playback.pause());
marquee1.addEventListener('mouseleave', () => playback.play());

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question