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

解决Vanilla JS跑马灯效果中SVG抖动问题

解决原生JS跑马灯中SVG/图片抖动问题

我用原生JavaScript实现了跑马灯效果,功能正常,但SVG(及图片)在移动时出现抖动现象。以下是原实现代码:

<div class="marquee">
  <h1>Nepal <svg version="1.1" viewBox="0 0 36 31" xmlns="http://www.w3.org/2000/svg"><path d="M8.80476 8.17844V12.3988H3.9993V4.25693H8.79846V8.17844H8.80476ZM32.4101 3.87271V0H20.0028V3.87271H16.0035V0H3.60252V3.87271H0V15.497H3.60252V19.76H7.60182V23.2485H11.6011V27.5115H15.6004V31H20.3996V27.5115H24.3989V23.2485H28.3982V19.76H32.3975V15.497H36V3.87271" fill="#DA2269"/></svg> Himalayas <svg version="1.1" viewBox="0 0 36 31" xmlns="http://www.w3.org/2000/svg"><path d="M8.80476 8.17844V12.3988H3.9993V4.25693H8.79846V8.17844H8.80476ZM32.4101 3.87271V0H20.0028V3.87271H16.0035V0H3.60252V3.87271H0V15.497H3.60252V19.76H7.60182V23.2485H11.6011V27.5115H15.6004V31H20.3996V27.5115H24.3989V23.2485H28.3982V19.76H32.3975V15.497H36V3.87271" fill="#DA2269"/></svg> Mountains <svg version="1.1" viewBox="0 0 36 31" xmlns="http://www.w3.org/2000/svg"><path d="M8.80476 8.17844V12.3988H3.9993V4.25693H8.79846V8.17844H8.80476ZM32.4101 3.87271V0H20.0028V3.87271H16.0035V0H3.60252V3.87271H0V15.497H3.60252V19.76H7.60182V23.2485H11.6011V27.5115H15.6004V31H20.3996V27.5115H24.3989V23.2485H28.3982V19.76H32.3975V15.497H36V3.87271" fill="#DA2269"/></svg> Everest</h1>
</div>

<style>
.marquee {
  overflow: hidden;
  border-top: 1px solid #000;
  border-bottom: 1px solid #000;
  display: flex;
}

.marquee h1{
  font-size: 5em;
  white-space: nowrap;
  text-transform: uppercase
}

.marquee h1 svg {
  width: auto;
  height: 60px;
}
</style>

<script>
function Marquee(selector, speed) {
  const parentSelector = document.querySelector(selector);
  const clone = parentSelector.innerHTML;
  const firstElement = parentSelector.children[0];
  let i = 0;
  console.log(firstElement);
  parentSelector.insertAdjacentHTML('beforeend', clone);
  parentSelector.insertAdjacentHTML('beforeend', clone);

  setInterval(function () {
    firstElement.style.marginLeft = `-${i}px`;
    if (i > firstElement.clientWidth) {
      i = 0;
    }
    i = i + speed;
  }, 0);
}

window.addEventListener('load', () => Marquee('.marquee', 0.2))
</script>

解决抖动的核心方案

抖动主要源于margin-left触发的频繁重排、setInterval和浏览器刷新不同步,以及亚像素渲染问题,可通过以下几点修复:

  • 用transform: translateX()替代margin-left:transform属性由GPU加速处理,不会触发页面重排,动画更平滑。
  • 替换setInterval为requestAnimationFrame:该API会和浏览器的刷新频率(通常60Hz)同步执行,避免丢帧导致的抖动。
  • 添加渲染优化提示:给运动元素添加will-change: transform,让浏览器提前分配资源优化渲染。
  • 优化SVG渲染:给SVG添加shape-rendering: crispEdges,避免亚像素渲染导致的模糊抖动。

修改后的完整代码

<div class="marquee">
  <h1>Nepal <svg version="1.1" viewBox="0 0 36 31" xmlns="http://www.w3.org/2000/svg"><path d="M8.80476 8.17844V12.3988H3.9993V4.25693H8.79846V8.17844H8.80476ZM32.4101 3.87271V0H20.0028V3.87271H16.0035V0H3.60252V3.87271H0V15.497H3.60252V19.76H7.60182V23.2485H11.6011V27.5115H15.6004V31H20.3996V27.5115H24.3989V23.2485H28.3982V19.76H32.3975V15.497H36V3.87271" fill="#DA2269"/></svg> Himalayas <svg version="1.1" viewBox="0 0 36 31" xmlns="http://www.w3.org/2000/svg"><path d="M8.80476 8.17844V12.3988H3.9993V4.25693H8.79846V8.17844H8.80476ZM32.4101 3.87271V0H20.0028V3.87271H16.0035V0H3.60252V3.87271H0V15.497H3.60252V19.76H7.60182V23.2485H11.6011V27.5115H15.6004V31H20.3996V27.5115H24.3989V23.2485H28.3982V19.76H32.3975V15.497H36V3.87271" fill="#DA2269"/></svg> Mountains <svg version="1.1" viewBox="0 0 36 31" xmlns="http://www.w3.org/2000/svg"><path d="M8.80476 8.17844V12.3988H3.9993V4.25693H8.79846V8.17844H8.80476ZM32.4101 3.87271V0H20.0028V3.87271H16.0035V0H3.60252V3.87271H0V15.497H3.60252V19.76H7.60182V23.2485H11.6011V27.5115H15.6004V31H20.3996V27.5115H24.3989V23.2485H28.3982V19.76H32.3975V15.497H36V3.87271" fill="#DA2269"/></svg> Everest</h1>
</div>

<style>
.marquee {
  overflow: hidden;
  border-top: 1px solid #000;
  border-bottom: 1px solid #000;
  display: flex;
}

.marquee h1{
  font-size: 5em;
  white-space: nowrap;
  text-transform: uppercase;
  will-change: transform; /* 提前告知浏览器元素将变换 */
}

.marquee h1 svg {
  width: auto;
  height: 60px;
  shape-rendering: crispEdges; /* 优化SVG渲染,避免亚像素模糊 */
}
</style>

<script>
function Marquee(selector, speed) {
  const parentSelector = document.querySelector(selector);
  const clone = parentSelector.innerHTML;
  const firstElement = parentSelector.children[0];
  let position = 0;

  parentSelector.insertAdjacentHTML('beforeend', clone);
  parentSelector.insertAdjacentHTML('beforeend', clone);

  function animate() {
    position += speed;
    // 当元素完全移出左侧时重置位置
    if (position >= firstElement.clientWidth) {
      position = 0;
    }
    // 使用transform实现平移
    firstElement.style.transform = `translateX(-${position}px)`;
    requestAnimationFrame(animate);
  }

  requestAnimationFrame(animate);
}

window.addEventListener('load', () => Marquee('.marquee', 0.2))
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 21:45:33