๐Ÿ’ป FE/๐Ÿ“ JS

MDN ๋ฒˆ์—ญ | Window: requestAnimationFrame() method

Roy Miller 2025. 3. 21. 19:33

window.requestAnimationFrame() ์™„๋ฒฝ ์ •๋ฆฌ (MDN Web Docs)

์ด ๋ฌธ์„œ๋Š” MDN Web Docs์˜ window.requestAnimationFrame() ํŽ˜์ด์ง€๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ต์‹ฌ ๋‚ด์šฉ์„ ์ƒ์„ธํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๊ณ , ์ดํ•ด๋ฅผ ๋•๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ ์„ค๋ช…๊ณผ ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

1. requestAnimationFrame()์ด๋ž€?

  • ์ •์˜: window.requestAnimationFrame()์€ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์ˆ˜ํ–‰ํ•˜๊ธฐ๋ฅผ ์›ํ•˜๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์•Œ๋ฆฌ๊ณ , ๋‹ค์Œ ๋ฆฌํŽ˜์ธํŠธ(repaint)๊ฐ€ ์ง„ํ–‰๋˜๊ธฐ ์ „์— ํ•ด๋‹น ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋„๋ก ์š”์ฒญํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๋ธŒ๋ผ์šฐ์ €์˜ ๋ Œ๋”๋ง ์ฃผ๊ธฐ์— ๋งž์ถฐ์„œ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” API์ž…๋‹ˆ๋‹ค.
  • ๋™์ž‘ ๋ฐฉ์‹:
    1. requestAnimationFrame()์— ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
    2. ๋ธŒ๋ผ์šฐ์ €๋Š” ๋‹ค์Œ ๋ฆฌํŽ˜์ธํŠธ(ํ™”๋ฉด ๊ฐฑ์‹ ) ์ „์— ์ด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    3. ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋‚ด์—์„œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ด€๋ จ DOM ์กฐ์ž‘(์Šคํƒ€์ผ ๋ณ€๊ฒฝ ๋“ฑ)์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    4. ํ•„์š”ํ•˜๋‹ค๋ฉด, ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋‹ค์‹œ requestAnimationFrame()์„ ํ˜ธ์ถœํ•˜์—ฌ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ณ„์† ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. (์žฌ๊ท€์  ํ˜ธ์ถœ)
  • ์žฅ์ :
    • ๋ถ€๋“œ๋Ÿฌ์šด ์• ๋‹ˆ๋ฉ”์ด์…˜: ๋ธŒ๋ผ์šฐ์ €์˜ ๋ฆฌํŽ˜์ธํŠธ ์ฃผ๊ธฐ์— ๋งž์ถฐ์„œ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์‹คํ–‰ํ•˜๋ฏ€๋กœ, setInterval์ด๋‚˜ setTimeout์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋ถ€๋“œ๋Ÿฝ๊ณ  ์ž์—ฐ์Šค๋Ÿฌ์šด ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์„ฑ๋Šฅ ์ตœ์ ํ™”:
      • ๋น„ํ™œ์„ฑ ํƒญ ์ตœ์ ํ™”: ๋ธŒ๋ผ์šฐ์ € ํƒญ์ด ๋น„ํ™œ์„ฑํ™”(๋ฐฑ๊ทธ๋ผ์šด๋“œ์— ์žˆ๊ฑฐ๋‚˜, ์ตœ์†Œํ™”๋œ ๊ฒฝ์šฐ)๋˜๋ฉด requestAnimationFrame()์€ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ์‹คํ–‰์„ ์ผ์‹œ ์ค‘์ง€ํ•˜์—ฌ CPU/GPU ์‚ฌ์šฉ๋Ÿ‰์„ ์ค„์ž…๋‹ˆ๋‹ค. ๋ฐฐํ„ฐ๋ฆฌ ์†Œ๋ชจ๋ฅผ ์ค„์ด๊ณ , ๋‹ค๋ฅธ ์ž‘์—…์— ๋ฆฌ์†Œ์Šค๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
      • ํ”„๋ ˆ์ž„ ์†๋„ ์กฐ์ ˆ: ๋ธŒ๋ผ์šฐ์ €๋Š” ํ˜„์žฌ ์‹œ์Šคํ…œ ๋ถ€ํ•˜ ๋ฐ ๋””์Šคํ”Œ๋ ˆ์ด ์ฃผ์‚ฌ์œจ์— ๋งž์ถฐ์„œ requestAnimationFrame() ์ฝœ๋ฐฑ ํ˜ธ์ถœ ๋นˆ๋„๋ฅผ ์ž๋™์œผ๋กœ ์กฐ์ ˆํ•ฉ๋‹ˆ๋‹ค. ๋†’์€ ์ฃผ์‚ฌ์œจ(high refresh rate) ๋ชจ๋‹ˆํ„ฐ์—์„œ๋Š” ๋” ์ž์ฃผ ํ˜ธ์ถœํ•˜์—ฌ ๋” ๋ถ€๋“œ๋Ÿฌ์šด ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ œ๊ณตํ•˜๊ณ , ๋‚ฎ์€ ์ฃผ์‚ฌ์œจ ๋ชจ๋‹ˆํ„ฐ์—์„œ๋Š” ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ์„ ์ค„์ž…๋‹ˆ๋‹ค.
    • ๋™๊ธฐํ™”: requestAnimationFrame์œผ๋กœ ํ˜ธ์ถœ๋˜๋Š” ์ฝœ๋ฐฑํ•จ์ˆ˜๋Š”, ๋‹จ์ผ ํ”„๋ ˆ์ž„ ์•ˆ์—์„œ ๋ชจ๋‘ ์‹คํ–‰๋จ.
  • setInterval/setTimeout๊ณผ์˜ ๋น„๊ต
     
๊ธฐ๋Šฅ requestAnimationFrame setInterval / setTimeout
์• ๋‹ˆ๋ฉ”์ด์…˜ ์ตœ์ ํ™” ๋ธŒ๋ผ์šฐ์ € ์ตœ์ ํ™” (๋ถ€๋“œ๋Ÿฌ์›€) ์ตœ์ ํ™” ์—†์Œ (๋Š๊น€ ๊ฐ€๋Šฅ์„ฑ)
๋น„ํ™œ์„ฑ ํƒญ ์ฒ˜๋ฆฌ ์ž๋™ ์ผ์‹œ ์ค‘์ง€ (์„ฑ๋Šฅ ์ ˆ์•ฝ) ๊ณ„์† ์‹คํ–‰ (์ž์› ๋‚ญ๋น„)
ํ˜ธ์ถœ ์ฃผ๊ธฐ ๋ธŒ๋ผ์šฐ์ € ๋ฆฌํŽ˜์ธํŠธ ์ฃผ๊ธฐ ์ง€์ •๋œ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ (๋ฐ€๋ฆฌ์ดˆ)
์ •ํ™•๋„ ๋†’์Œ (๋ธŒ๋ผ์šฐ์ €์— ์ตœ์ ํ™”) ๋‚ฎ์Œ (์‹œ์Šคํ…œ ๋ถ€ํ•˜์— ๋”ฐ๋ผ ์ง€์—ฐ๋  ์ˆ˜ ์žˆ์Œ)
์ฃผ ์‚ฌ์šฉ ๋ชฉ์  ์• ๋‹ˆ๋ฉ”์ด์…˜, ๋ถ€๋“œ๋Ÿฌ์šด UI ๋ณ€ํ™” ์ฃผ๊ธฐ์ ์ธ ์ž‘์—…, ์ผ์ • ์‹œ๊ฐ„ ํ›„ ์‹คํ–‰ (์• ๋‹ˆ๋ฉ”์ด์…˜์—๋Š” ๋ถ€์ ํ•ฉ)

2. ๊ตฌ๋ฌธ (Syntax)

JavaScript

let requestId = window.requestAnimationFrame(callback);
  • callback: ๋‹ค์Œ ๋ฆฌํŽ˜์ธํŠธ ๋•Œ ํ˜ธ์ถœ๋  ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” _๋‹จ์ผ ์ธ์ˆ˜_๋กœ DOMHighResTimeStamp ๊ฐ’์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ’์€ requestAnimationFrame์ด ์ฝœ๋ฐฑ์„ ์‹คํ–‰ํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ์‹œ์ ์˜ ์ •๋ฐ€ํ•œ ์‹œ๊ฐ„(๋ฐ€๋ฆฌ์ดˆ ๋‹จ์œ„)์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. performance.now()๋กœ ์–ป์€ ๊ฐ’๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • requestId: requestAnimationFrame() ํ˜ธ์ถœ์„ ์‹๋ณ„ํ•˜๋Š” ๊ณ ์œ ํ•œ ์ˆซ์ž ID์ž…๋‹ˆ๋‹ค. ์ด ID๋ฅผ cancelAnimationFrame(requestId)์— ์ „๋‹ฌํ•˜์—ฌ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3. ์˜ˆ์ œ ์ฝ”๋“œ

3.1. ๊ฐ„๋‹จํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜

HTML

<!DOCTYPE html>
<html>
<head>
  <title>requestAnimationFrame Example</title>
  <style>
    #box {
      width: 100px;
      height: 100px;
      background-color: red;
      position: absolute;
      left: 0;
    }
  </style>
</head>
<body>
  <div id="box"></div>

  <script>
    const box = document.getElementById('box');
    let position = 0;
    let requestId;

    function animate() {
      position += 2; // ์ด๋™ ๊ฑฐ๋ฆฌ
      box.style.left = position + 'px'; // CSS ์†์„ฑ ๋ณ€๊ฒฝ (left)

      if (position < 200) {
          requestId = requestAnimationFrame(animate); // ๋‹ค์Œ ํ”„๋ ˆ์ž„ ์š”์ฒญ (์žฌ๊ท€ ํ˜ธ์ถœ)
      }

    }

    requestId = requestAnimationFrame(animate); // ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹œ์ž‘

    // ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ทจ์†Œ (์˜ˆ์‹œ)
    // setTimeout(() => {
    //   cancelAnimationFrame(requestId);
    // }, 2000); // 2์ดˆ ํ›„ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ค‘์ง€

  </script>
</body>
</html>
  • animate() ํ•จ์ˆ˜๋Š” ๋ฐ•์Šค์˜ left ์œ„์น˜๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™์‹œํ‚ค๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • requestAnimationFrame(animate)๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  • animate() ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋‹ค์‹œ requestAnimationFrame(animate)๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ณ„์† ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. (์žฌ๊ท€ ํ˜ธ์ถœ)
  • position์ด 200๋ณด๋‹ค ์ž‘์„ ๋•Œ๋งŒ ๋‹ค์Œ ํ”„๋ ˆ์ž„์„ ์š”์ฒญํ•˜์—ฌ, ๋ฐ•์Šค๊ฐ€ ํŠน์ • ์œ„์น˜๊นŒ์ง€๋งŒ ์ด๋™ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • setTimeout๊ณผ cancelAnimationFrame์„ ์‚ฌ์šฉํ•˜์—ฌ, ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ค‘๊ฐ„์— ๋ฉˆ์ถœ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3.2. ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜ ์• ๋‹ˆ๋ฉ”์ด์…˜ (Time-based animation)

requestAnimationFrame ์ฝœ๋ฐฑ์— ์ „๋‹ฌ๋˜๋Š” DOMHighResTimeStamp๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ”„๋ ˆ์ž„ ์†๋„์— ๊ด€๊ณ„์—†์ด ์ผ์ •ํ•œ ์†๋„๋กœ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

HTML

<!DOCTYPE html>
<html>
<head>
  <title>Time-based Animation</title>
  <style>
    #box {
      width: 100px;
      height: 100px;
      background-color: blue;
      position: absolute;
      left: 0;
    }
  </style>
</head>
<body>
  <div id="box"></div>

  <script>
    const box = document.getElementById('box');
    let start = null;
    const duration = 2000; // ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ง€์† ์‹œ๊ฐ„ (๋ฐ€๋ฆฌ์ดˆ)

    function animate(timestamp) {
      if (!start) start = timestamp; // ์ฒ˜์Œ ์‹œ์ž‘ ์‹œ๊ฐ„์„ ๊ธฐ๋ก
      const progress = timestamp - start; // ๊ฒฝ๊ณผ ์‹œ๊ฐ„ ๊ณ„์‚ฐ

      // 0 ~ 1 ์‚ฌ์ด์˜ ์ง„ํ–‰๋ฅ  ๊ณ„์‚ฐ (duration์œผ๋กœ ๋‚˜๋ˆ„๊ธฐ)
      const normalizedProgress = Math.min(progress / duration, 1);

      // ์ง„ํ–‰๋ฅ ์— ๋”ฐ๋ผ ์œ„์น˜ ๊ณ„์‚ฐ (ease-out ํ•จ์ˆ˜ ์ ์šฉ)
      const position = easeOutCubic(normalizedProgress) * 300; // ์ตœ๋Œ€ 300px ์ด๋™

      box.style.left = position + 'px';


      if (progress < duration) {
        requestAnimationFrame(animate); // ๋‹ค์Œ ํ”„๋ ˆ์ž„ ์š”์ฒญ
      }
    }

    // Ease-out cubic ํ•จ์ˆ˜ (๋ถ€๋“œ๋Ÿฌ์šด ๊ฐ์† ํšจ๊ณผ)
    function easeOutCubic(t) {
      return 1 - Math.pow(1 - t, 3);
    }
    //๋‹ค๋ฅธ easing ํ•จ์ˆ˜ ์˜ˆ์‹œ
   /* function easeInOutQuad(t: number): number {
        return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
    }*/

    requestAnimationFrame(animate); // ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹œ์ž‘
  </script>
</body>
</html>
  • animate(timestamp): timestamp ์ธ์ˆ˜๋Š” requestAnimationFrame์ด ์ฝœ๋ฐฑ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜๋Š” ํ˜„์žฌ ์‹œ๊ฐ„(DOMHighResTimeStamp)์ž…๋‹ˆ๋‹ค.
  • start: ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹œ์ž‘ ์‹œ๊ฐ„์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. animate() ํ•จ์ˆ˜๊ฐ€ ์ฒ˜์Œ ํ˜ธ์ถœ๋  ๋•Œ performance.now()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ดˆ๊ธฐํ™”๋ฉ๋‹ˆ๋‹ค.
  • progress: ์‹œ์ž‘ ์‹œ๊ฐ„(start)์œผ๋กœ๋ถ€ํ„ฐ ๊ฒฝ๊ณผ๋œ ์‹œ๊ฐ„์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
  • normalizedProgress: ๊ฒฝ๊ณผ ์‹œ๊ฐ„์„ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ง€์† ์‹œ๊ฐ„(duration)์œผ๋กœ ๋‚˜๋ˆ„์–ด 0๊ณผ 1 ์‚ฌ์ด์˜ ์ง„ํ–‰๋ฅ ์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. Math.min์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง„ํ–‰๋ฅ ์ด 1์„ ๋„˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • easeOutCubic(normalizedProgress): easing ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ€๋“œ๋Ÿฌ์šด ๊ฐ€์†/๊ฐ์† ํšจ๊ณผ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • position: easing ํ•จ์ˆ˜์—์„œ ๋ฐ˜ํ™˜๋œ ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ, ์ด๋™ํ•  ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
  • box.style.left = position + 'px';: ๊ณ„์‚ฐ๋œ ์œ„์น˜๋กœ ๋ฐ•์Šค๋ฅผ ์ด๋™์‹œํ‚ต๋‹ˆ๋‹ค.
  • if (progress < duration): ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜์œผ๋ฉด requestAnimationFrame(animate)๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜์—ฌ ๋‹ค์Œ ํ”„๋ ˆ์ž„์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

4. cancelAnimationFrame()

  • ์ •์˜: cancelAnimationFrame()์€ ์ด์ „์— requestAnimationFrame()์œผ๋กœ ์˜ˆ์•ฝ๋œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํ”„๋ ˆ์ž„ ์š”์ฒญ์„ ์ทจ์†Œํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
  • ๊ตฌ๋ฌธ:
      window.cancelAnimationFrame(requestId);
    • requestId: requestAnimationFrame()์ด ๋ฐ˜ํ™˜ํ•œ ID์ž…๋‹ˆ๋‹ค.
  • JavaScript
  • ์˜ˆ์ œ:
      let requestId = requestAnimationFrame(animate);
    
      // ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ทจ์†Œ
      cancelAnimationFrame(requestId);
  • JavaScript

์š”์•ฝ

requestAnimationFrame()์€ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ๋ถ€๋“œ๋Ÿฝ๊ณ  ํšจ์œจ์ ์ธ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ํ•„์ˆ˜์ ์ธ API์ž…๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์˜ ๋ฆฌํŽ˜์ธํŠธ ์ฃผ๊ธฐ์— ๋งž์ถฐ์„œ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์—…๋ฐ์ดํŠธํ•˜๋ฏ€๋กœ, setInterval์ด๋‚˜ setTimeout์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์„ฑ๋Šฅ์ด ์ข‹๊ณ  ์ž์—ฐ์Šค๋Ÿฌ์šด ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. cancelAnimationFrame()์„ ์‚ฌ์šฉํ•˜์—ฌ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ค‘์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๊ตฌํ˜„ํ•˜๋ฉด ํ”„๋ ˆ์ž„ ์†๋„์— ๊ด€๊ณ„์—†์ด ์ผ์ •ํ•œ ์†๋„๋กœ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame

 

Window: requestAnimationFrame() method - Web APIs | MDN

The window.requestAnimationFrame() method tells the browser you wish to perform an animation. It requests the browser to call a user-supplied callback function before the next repaint.

developer.mozilla.org