You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

requestAnimationFrame无法取消及多动画冲突问题的修复方案问询

解决方案

问题根源

window.cancelAnimationFrame的参数必须是**window.requestAnimationFrame返回的请求ID**,直接传入fall或jump函数无法取消对应动画——浏览器无法识别要终止的是哪个动画请求,导致下落动画继续运行,与新触发的跳跃动画冲突。

修复步骤

  1. 新增变量currentAnimationId,用于存储当前正在运行的动画请求ID。
  2. 每次调用requestAnimationFrame时,将返回的ID赋值给currentAnimationId。
  3. 取消动画时,使用currentAnimationId调用cancelAnimationFrame,并重置ID。
  4. 触发新动画前,先取消当前所有正在运行的动画,避免多动画冲突。

修改后的JavaScript代码

let up = false
let height = 0
let speed = 1
let target = height + 150
let rect = document.getElementById("rect")
let stateText = document.getElementById("state")
let upText = document.getElementById("up")
let heightText = document.getElementById("height")
let targetText = document.getElementById("target")
// 新增:存储当前动画请求ID
let currentAnimationId = null

stateText.innerText = "状态:空闲"
upText.innerText = "上升中:"
heightText.innerText = "高度:0"
targetText.innerText = "目标高度:" + target


function jump() {
  up = true
  upText.innerText = "上升中:" + up
  stateText.innerText = "状态:跳跃"
  if (height < target) {
    console.log("调试:跳跃")
    height += speed
    heightText.innerText = "高度:" + height
    rect.setAttribute("y", 280 - height)
    // 存储请求ID
    currentAnimationId = window.requestAnimationFrame(jump)
  } else {
    up = false
    // 取消当前跳跃动画
    window.cancelAnimationFrame(currentAnimationId)
    // 触发下落并存储ID
    currentAnimationId = window.requestAnimationFrame(fall)
  }
}

function fall() {
  up = false
  stateText.innerText = "状态:下落"
  upText.innerText = "上升中:" + up
  if (height > -1) {
    console.log("调试:下落")
    height -= speed
    heightText.innerText = "高度:" + height
    rect.setAttribute("y", 280 - height)
    // 存储请求ID
    currentAnimationId = window.requestAnimationFrame(fall)
  } else {
    // 落地后取消动画
    window.cancelAnimationFrame(currentAnimationId)
    currentAnimationId = null
    height = 0
    stateText.innerText = "状态:空闲"
    heightText.innerText = "高度:" + height
    up = false
  }
}

function handleClick() {
  target = height + 150
  targetText.innerText = "目标高度:" + target
  
  // 先取消当前所有正在运行的动画
  if (currentAnimationId) {
    window.cancelAnimationFrame(currentAnimationId)
    currentAnimationId = null
  }
  
  // 直接触发跳跃动画
  up = true
  currentAnimationId = window.requestAnimationFrame(jump)
}

内容的提问来源于stack exchange,提问作者louislugas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 11:14:55