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

手电筒照射span时停止其动画的JavaScript实现问题

问题分析

核心问题出在照射检测的触发时机:当前你可能仅在mousemove事件里判断span是否被手电筒覆盖,鼠标静止时该事件不再触发,自然不会执行停止动画的逻辑。

解决方案
  1. 将照射检测移入动画循环(loop函数):
    不管鼠标是否移动,每帧都检测所有span是否处于手电筒范围内,确保静止时也能持续判断。
  2. 优化动画暂停逻辑:
    给每个span添加状态标记(比如data-is-paused),避免重复触发延迟定时器;同时依托requestAnimationFrame维护动画,保证暂停/恢复状态同步。
关键代码片段
// 假设手电筒元素为#flashlight,字母span类为.letter
const flashlight = document.getElementById('flashlight');
const letters = document.querySelectorAll('.letter');

// 每帧执行的照射检测逻辑
function checkFlashlightCoverage() {
  const flashlightRect = flashlight.getBoundingClientRect();
  
  letters.forEach(letter => {
    const letterRect = letter.getBoundingClientRect();
    // 判断矩形是否相交(即span被照射)
    const isOverlapping = !(
      flashlightRect.right < letterRect.left ||
      flashlightRect.left > letterRect.right ||
      flashlightRect.bottom < letterRect.top ||
      flashlightRect.top > letterRect.bottom
    );

    if (isOverlapping) {
      // 未标记暂停时,启动5秒延迟停止
      if (!letter.dataset.isPaused) {
        letter.dataset.isPaused = 'true';
        const timerId = setTimeout(() => {
          letter.style.animationPlayState = 'paused';
        }, 5000);
        letter.dataset.timerId = timerId;
      }
    } else {
      // 离开照射范围,恢复动画并清除状态
      if (letter.dataset.isPaused) {
        letter.style.animationPlayState = 'running';
        clearTimeout(letter.dataset.timerId);
        delete letter.dataset.isPaused;
        delete letter.dataset.timerId;
      }
    }
  });
}

// 把检测逻辑加入动画循环
function loop() {
  // 原有的手电筒跟随等动画逻辑
  checkFlashlightCoverage(); // 新增持续检测
  requestAnimationFrame(loop);
}
loop();
注意事项
  • 不要依赖mousemove做持续检测,鼠标静止时该事件不会触发;
  • 用getBoundingClientRect()判断元素相交是最可靠的方式,避免坐标计算误差;
  • 给每个span加状态标记,防止重复创建定时器,避免动画状态混乱;
  • 确保检测逻辑放在loop函数每帧都会执行的位置,适配你基于模板修改的代码结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 13:43:22