以恒定速度响应的背景滚动

Responsive background scrolling with constant speed

我想使用带有滚动背景图片的响应式div。

在示例中,我展示了它的大小。我希望整个滚动保持不变 - 所以小的 div 应该花费 x 秒,大的 div 也应该花费 x 秒(而不是小的花费更少的时间来完成整个图像平移较大的那个)。

我试过在 background-position-x 中使用百分比值,但它停止了动画。

.offset {
  background-image: url('https://upload.wikimedia.org/wikipedia/commons/c/c4/PM5544_with_non-PAL_signals.png');
  background-size: 100%;
  animation: slideLeft768px 5s linear infinite;
}

.div1 {
  width: 76.8px;
  height: 57.6px;
}

.div2 {
  width: 768px;
  height: 576px;
}

@keyframes slideLeft768px {
  0% {
    background-position-x: 768px;
  }
  100% {
    background-position-x: 0px;
  }
}
<div class="offset div1"></div>
<div class="offset div2"></div>

====================

这是基于 Temani Afif 的回答:

.offset {
  background-image: url('https://upload.wikimedia.org/wikipedia/commons/c/c4/PM5544_with_non-PAL_signals.png');
  background-size: 100%;
  animation: slideLeft 5s linear infinite;
  width: var(--p);
  --p: 40vw;
  height: 30vw;
}
.div1 {
    --p: 12vw;
    height: 9vw;
}

@keyframes slideLeft {
  0% {
    background-position-x: var(--p);
  }
  100% {
    background-position-x: 0px;
  }
}  
<div class="offset div1"></div>
<div class="offset div2"></div>

我让它只使用响应单元,所以它会在您调整 window 大小时进行调整。

你可以考虑CSS变量使动画动态化:

.offset {
  background-image: url('https://upload.wikimedia.org/wikipedia/commons/c/c4/PM5544_with_non-PAL_signals.png');
  background-size: 100%;
  animation: slideLeft768px 5s linear infinite;
  width: var(--p);
}

.div1 {
  --p: 76.8px;
  height: 57.6px;
}

.div2 {
  --p:768px;
  height: 576px;
}

@keyframes slideLeft768px {
  0% {
    background-position: var(--p,0px) 0px;
  }
  100% {
    background-position: 0px 0px;
  }
}
<div class="offset div1"></div>
<div class="offset div2"></div>

并且由于您使用的是具有已知尺寸的相同图像,因此您可以像下面这样优化代码:

.offset {
  background-image: url('https://upload.wikimedia.org/wikipedia/commons/c/c4/PM5544_with_non-PAL_signals.png');
  background-size: 100%;
  animation: slideLeft768px 5s linear infinite;
  width: calc(768px * var(--p,1));
  height: calc(576px * var(--p,1));
}

.div1 {
  --p: 0.1;
}

.div2 {
  --p:0.2;
}

@keyframes slideLeft768px {
  0% {
    background-position: calc(768px * var(--p,1)) 0px;
  }
  100% {
    background-position: 0px 0px;
  }
}
<div class="offset div1"></div>
<div class="offset div2"></div>
<div class="offset" style="--p:0.8"></div>

您还可以查看此答案 () 以了解为什么百分比值不起作用以及如何使其起作用。

诀窍是使用百分比作为背景位置。由于将 background-size 设置为 100% 使得这不可能,我们需要将其设置为另一个值。

一个技巧是为此使用填充。创建一个与宽度尺寸相同的填充。使背景起源于paddin box,并裁剪内容框,现在我们可以将大小设置为50%。在视觉上,什么都不会改变。 (如果额外填充有问题,您可以设置负边距或剪辑路径)。现在,背景位置可以按百分比移动:

.offset {
  background-image: url('https://upload.wikimedia.org/wikipedia/commons/c/c4/PM5544_with_non-PAL_signals.png');
  background-size: 50%;
  background-origin: border-box;
  background-clip: content-box;
  animation: slideLeft768px 5s linear infinite;
}

.div1 {
  width: 76.8px;
  padding-right: 76.8px;
  height: 57.6px;
}

.div2 {
  width: 768px;
  padding-right: 768px;
  height: 576px;
}

@keyframes slideLeft768px {
  0% {
    background-position-x: 100%;
  }
  100% {
    background-position-x: 0%;
  }
}
<div class="offset div1"></div>
<div class="offset div2"></div>