CSS无限平移动画结合JS滚轮事件的卡顿问题求助
问题原因
CSS动画的transform属性优先级高于行内样式设置的transform,哪怕动画暂停,元素的transform依然由动画的当前帧状态控制,所以直接设置widgets.style.transform不会生效。
解决方案
我们需要暂停动画,同时手动维护当前的偏移量,通过滚轮事件调整这个偏移值并应用到元素上,鼠标离开后可选择从当前位置恢复自动动画。
修改后的完整代码:
HTML
<div class="main"> <div class="widgets"> <div class="wid">classeviva</div> <div class="wid">moodle</div> <div class="wid">circolari</div> <div class="wid">gmail</div> <div class="wid">ECDL</div> <div class="wid">cambdridge assessment english</div> <div class="wid">PON</div> <div class="wid">erasmus+</div> <div class="wid">amministrazione trasparente</div> <div class="wid">albo online</div> </div> </div>
CSS
.main .widgets { display: flex; animation: marquee 20s linear infinite; transform: translateX(100%); /* 与动画起始帧保持一致 */ } .main .widgets:hover, .main .widgets.is-manual { animation-play-state: paused; } @keyframes marquee { 0% { transform: translateX(100%); } 100% { transform: translateX(-100%); } } .wid { min-width: 200px; margin: 0 10px; padding: 8px 12px; background: #f0f0f0; border-radius: 4px; }
JavaScript
const widgets = document.querySelector('.widgets'); let currentOffset = 0; const initialOffset = window.innerWidth; // 将动画起始的100%转换为窗口宽度像素值 currentOffset = initialOffset; // 监听滚轮事件 widgets.addEventListener('wheel', (e) => { e.preventDefault(); // 阻止页面整体滚动 widgets.classList.add('is-manual'); // 强制暂停动画 // 根据滚轮方向调整偏移,deltaY正为向下滚(左移),负为向上滚(右移) currentOffset += e.deltaY * -1; // 系数可调整,控制滚动灵敏度 widgets.style.transform = `translateX(${currentOffset}px)`; }); // 鼠标离开后从当前位置恢复自动动画 widgets.addEventListener('mouseleave', () => { widgets.classList.remove('is-manual'); // 计算当前位置对应的动画进度,避免跳转 const totalDistance = initialOffset * 2; // 从100%到-100%的总移动距离 const progress = (initialOffset - currentOffset) / totalDistance; const animationDuration = 20; // 动画总时长(秒) widgets.style.animationDelay = `-${progress * animationDuration}s`; });
代码说明
- 新增
is-manual类,确保滚轮控制时动画始终处于暂停状态 - 用
currentOffset变量维护当前水平偏移量,滚轮事件中根据方向动态调整 - 初始化时将百分比偏移转换为像素值,方便后续计算
- 鼠标离开时,通过计算当前位置对应的动画进度,设置
animationDelay让动画从当前位置无缝续播 - 调用
e.preventDefault()避免滚轮触发页面整体滚动
内容的提问来源于stack exchange,提问作者Francesco Pauselli
相关产品推荐
相关产品推荐

