全角元素的循环视差效果在 CSS / JS 中不断跳跃

Looping parallax effect on full-width element keeps jumping in CSS / JS

我的首选最终目标是拥有一个性能友好的背景,可以平滑循环而不会跳转。我在网上找到的所有资源要么对性能不太友好,要么只适用于具有设定宽度的元素。

目前一切正常,但背景在不同屏幕上的缩放效果不佳,偶尔会出现较大的跳跃。我假设跳跃是由于元素的翻译错误,但我还没有看到一个好的解决方案。将元素的宽度设置为 200% 并将它们转换为超过 -50% 似乎是一个 hacky 解决方案,我觉得应该有更好的方法来做到这一点。

我更希望找到一个全 CSS 的解决方案,但如果没有别的办法,求助于 JS 也可以。

Fiddle: https://jsfiddle.net/r4fz0Lot/3/

代码:

* { box-sizing: border-box; }
html, body, #container { width: 100%; height: 100%; }
body { margin: 0; }

#container {
  background-color: rgba(0, 0, 0, 0.9);
  image-rendering: pixelated;
  overflow: hidden;
  position: fixed;
}

#stars {
  background: url('https://i.imgur.com/Ym03Zkf.png') repeat 0 0;
  animation: loop 25s linear infinite;
  z-index: 1;
}

#mountains {
  background: url('https://i.imgur.com/jfef1r3.png') repeat-x 0 bottom;
  animation: loop 20s linear infinite;
  z-index: 2;
}

#ground {
  background: url('https://i.imgur.com/P13CzUo.png') repeat-x 0 bottom;
  animation: loop 15s linear infinite;
  z-index: 3;
}

#stars, #mountains, #ground {
  width: 200%; height: 100%;
  background-size: 30%;
  bottom: 0; left: 0;
  position: fixed;
}

@keyframes loop {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
<div id="container">
  <div id="ground"></div>
  <div id="mountains"></div>
  <div id="stars"></div>
</div>

您将 background-size 设置为 30%,因此您需要翻译 30% 的倍数才能翻译 "one image unit"

* { box-sizing: border-box; }
html, body, #container { width: 100%; height: 100%; }
body { margin: 0; }

#container {
  background-color: rgba(0, 0, 0, 0.9);
  image-rendering: pixelated;
  overflow: hidden;
  position: fixed;
}

#stars {
  background: url('https://i.imgur.com/Ym03Zkf.png') repeat 0 0;
  animation: loop 8s linear infinite;
  z-index: 1;
}

#mountains {
  background: url('https://i.imgur.com/jfef1r3.png') repeat-x 0 bottom;
  animation: loop 6s linear infinite;
  z-index: 2;
}

#ground {
  background: url('https://i.imgur.com/P13CzUo.png') repeat-x 0 bottom;
  animation: loop 5s linear infinite;
  z-index: 3;
}

#stars, #mountains, #ground {
  width: 200%; height: 100%;
  background-size: 30%;
  bottom: 0; left: 0;
  position: fixed;
}

@keyframes loop {
  from { transform: translateX(0); }
  to { transform: translateX(-30%); }
}
<div id="container">
  <div id="ground"></div>
  <div id="mountains"></div>
  <div id="stars"></div>
</div>