requestAnimationFrame的用法

43 篇文章 3 订阅
6 篇文章 0 订阅

85. requestAnimationFrame的用法

requestAnimationFrame 是一个用于在浏览器中执行动画的 API。它通过在浏览器的重绘阶段调用指定的回调函数,实现流畅且高效的动画效果。在本文中,我们将详细介绍 requestAnimationFrame 的用法,并给出一些代码示例。

什么是 requestAnimationFrame?

requestAnimationFrame 是浏览器提供的 JavaScript API,用于优化动画的执行。与使用定时器(如 setTimeoutsetInterval)不同,requestAnimationFrame 利用浏览器的重绘机制,在每个浏览器重绘的时刻执行指定的回调函数,以实现更加流畅和高效的动画效果。

requestAnimationFrame 的用法

使用 requestAnimationFrame 很简单。只需要将你的动画逻辑包装在一个回调函数中,然后通过调用 requestAnimationFrame 来请求浏览器在下一次重绘时执行这个回调函数。

下面是一个简单的示例,展示了如何使用 requestAnimationFrame 实现一个简单的动画效果:

function animate() {
  // 更新动画状态

  // 绘制动画效果

  requestAnimationFrame(animate);
}

// 启动动画
requestAnimationFrame(animate);

在上面的代码中,我们定义了一个 animate 函数,这个函数包含了我们的动画逻辑。在 animate 函数内部,我们首先更新动画的状态,然后绘制动画效果。最后,我们再次调用 requestAnimationFrame(animate),以实现连续的动画效果。

requestAnimationFrame 的优势

相比于使用定时器来实现动画效果,requestAnimationFrame 具有以下优势:

  1. 更佳的性能和效率requestAnimationFrame 使用浏览器的重绘机制,在合适的时机执行动画回调函数,以保证最佳的性能和效率。

  2. 避免卡顿和掉帧:由于 requestAnimationFrame 的执行时间与浏览器的重绘间隔相关,因此可以避免动画在复杂场景下出现卡顿和掉帧的情况。

  3. 节省系统资源:当页面处于非激活状态时,requestAnimationFrame 会自动停止执行,从而节省系统资源。

兼容性注意事项

虽然 requestAnimationFrame 是现代浏览器提供的标准 API,但在使用时仍需注意兼容性问题。为了兼容不支持 requestAnimationFrame 的旧版本浏览器,你可以使用 polyfill 或使用工具库(如 TweenMax)来处理兼容性问题。

总结

requestAnimationFrame 是一个用于在浏览器中执行动画的 API,它能够以更佳的性能和效率实现流畅的动画效果。通过在

浏览器的重绘阶段调用指定的回调函数,requestAnimationFrame 可以避免卡顿和掉帧,并节省系统资源。在使用 requestAnimationFrame 时,要注意兼容性问题,并考虑使用 polyfill 或工具库来处理兼容性。

每日一游 - 井字棋小游戏

井字棋

<!DOCTYPE html>
<html>
<head>
  <title>Tic Tac Toe</title>
  <style>
    h1 {
      text-align: center;
    }
    .board {
      display: table;
      margin: 0 auto;
    }

    .row {
      display: table-row;
    }

    .cell {
      display: table-cell;
      width: 80px;
      height: 80px;
      border: 1px solid #000;
      font-size: 48px;
      text-align: center;
      vertical-align: middle;
      cursor: pointer;
    }

    .cell.x {
      color: #f00;
    }

    .cell.o {
      color: #00f;
    }

    .cell:hover {
      background-color: #eee;
    }

    .message {
      font-size: 24px;
      margin-top: 16px;
      text-align: center;
    }

    .restart-button {
      display: block;
      margin: 16px auto;
      padding: 8px 16px;
      font-size: 16px;
      background-color: #eee;
      border: none;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <h1>井字棋游戏</h1>
  <div class="board">
    <div class="row">
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
    </div>
    <div class="row">
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
    </div>
    <div class="row">
      <div class="cell"></div>
      <div class="cell"></div>
      <div class="cell"></div>
    </div>
  </div>
  <div class="message"></div>
  <button class="restart-button">Restart</button>

  <script>
    document.addEventListener('DOMContentLoaded', function() {
      const board = document.querySelector('.board');
      const message = document.querySelector('.message');
      const cells = Array.from(document.querySelectorAll('.cell'));
      const restartButton = document.querySelector('.restart-button');

      let currentPlayer = 'X';
      let gameOver = false;

      function handleCellClick(event) {
        const cell = event.target;

        if (cell.textContent === '' && !gameOver) {
          cell.textContent = currentPlayer;
          cell.classList.add(currentPlayer === 'X' ? 'x' : 'o');

          if (checkWin()) {
            gameOver = true;
            message.textContent = `Player ${currentPlayer} wins!`;
          } else if (checkDraw()) {
            gameOver = true;
            message.textContent = "It's a draw!";
          } else {
            currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
          }
        }
      }

      function checkWin() {
        const winningCombinations = [
          [0, 1, 2], [3, 4, 5], [6, 7, 8], // Rows
          [0, 3, 6], [1, 4, 7], [2, 5, 8], // Columns
          [0, 4, 8], [2, 4, 6] // Diagonals
        ];

        return winningCombinations.some(combination => {
          const [a, b, c] = combination;
          return (
            cells[a].textContent &&
            cells[a].textContent === cells[b].textContent &&
            cells[a].textContent === cells[c].textContent
          );
        });
      }

      function checkDraw() {
        return cells.every(cell => cell.textContent);
      }

      function restartGame() {
        cells.forEach(cell => {
          cell.textContent = '';
          cell.classList.remove('x', 'o');
        });

        currentPlayer = 'X';
        gameOver = false;
        message.textContent = '';
      }

      cells.forEach(cell => {
        cell.addEventListener('click', handleCellClick);
      });

      restartButton.addEventListener('click', restartGame);
    });
  </script>
</body>
</html>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端每日三省

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值