动画CSS背景图案,无限滑动

Kam*_*her 4 css linear-gradients css-animations repeating-linear-gradient

我试图创建一个动画重复模式(水平滑动的斜条纹),作为加载块的占位符(li在这种情况下).

如何让动画平滑/连续,让幻觉模式无限滑动?

  • 如何计算元素width以使图案连续?(条纹不应该看起来破碎/中断).
  • 如何让它循环看起来不是重新启动而是无限滑动?(100%帧应该传递到0%帧而没有任何故障)

我的目标是拥有一个可以添加到任何块的类,并且在视觉上看起来像加载/处理.

注意:没有JS; 纯CSS.

li {
  display: inline-block;
  width: calc(20px * 8); /* how to calculate this, relative to the width (of the pattern or the step), to achieve pattern continuity exactly?
    Of course without doing trying&error to know it should be 24.75px * 8.
  */
  height: 200px;
  background-color: blue;

  background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, black 10px, black 20px);
  animation: loading-slide 1s linear infinite;

}
  @keyframes loading-slide {
    from { background-position: 0% 0% }
    to { background-position: 100% 0% }
  }
Run Code Online (Sandbox Code Playgroud)
<ul>
    <li>test
    <li>test
</ul>
Run Code Online (Sandbox Code Playgroud)

Tem*_*fif 6

应该是正确的公式(20px / cos(45deg)) * N.然后你可以简单地使它background-size成为200% 100%(比元素大两倍),你可以轻松地从左到右动画:

li {
  display: inline-block;
  width: calc( (20px / 0.707) * 3); /*cos(45deg) = 0.707*/
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(-45deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}

.alt li {
  width: calc( (20px / 0.707) * 6);
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

您可以考虑任何学位并根据需要调整公式.(20px / cos(90deg - |Xdeg|)) * NX之间-90deg90deg

用例子 -60deg

li {
  display: inline-block;
  width: calc((20px / 0.866) * var(--n,3)); /*cos(30deg) = 0.866*/
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(-60deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}

.alt li {
  --n:6;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

用例子 30deg

li {
  display: inline-block;
  width: calc((20px / 0.5) * var(--n,8)); /*cos(60deg) = 0.5*/
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(30deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}

.alt li {
  --n:12;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

用例子 80deg

li {
  display: inline-block;
  width: calc((20px / 0.9848) * var(--n,8)); /*cos(10deg) = 0.9848*/
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(80deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}

.alt li {
  --n:12;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

你可以清楚地识别出X=+/-90deg(垂直条纹)的微不足道的情况,cos(0)=1因此我们将得到公式20px * N.此外,当X=0(水平条纹)我们将拥有cos(90deg) = 0和任何宽度将工作,因为没有垂直模式(公式不再定义)

li {
  display: inline-block;
  width: calc(20px * var(--n,8)); 
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(90deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}

.alt li {
 background-image:repeating-linear-gradient(0deg, transparent, transparent 10px, black 10px, black 20px);
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

外面的价值怎么样[-90deg,90deg]

上面的范围已经涵盖180deg,因为我们正在处理对称的东西,所有的值都可以在该范围内表示.

示例:110deg与...相同-70deg

li {
  display: inline-block;
  width: calc((20px / 0.9396) * var(--n,8)); /*cos(20deg) = 0.9396*/
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(110deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}
.alt li {
  --n:12;
  background-image: repeating-linear-gradient(-70deg, transparent, transparent 10px, black 10px, black 20px);
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

示例:-150deg与...相同30deg

li {
  display: inline-block;
  width: calc((20px / 0.5) * var(--n,4)); /*cos(60deg) = 0.5*/
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  background-image: repeating-linear-gradient(-150deg, transparent, transparent 10px, black 10px, black 20px);
  background-size: 200% 100%;
  background-color: blue;
  animation: loading-slide 3s linear infinite;
}
.alt li {
  --n:6;
  background-image: repeating-linear-gradient(30deg, transparent, transparent 10px, black 10px, black 20px);
}

@keyframes loading-slide {
  from {
    background-position: left;
  }
  to {
    background-position: right;
  }
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

基本上我们添加/删除,180deg直到我们进入内部[-90deg,90deg]才能应用公式.


查看此答案以获取有关如何background-size/ background-position工作的更多详细信息:https://stackoverflow.com/a/51734530/8620333


另一种方法

这是一个完全不同的想法,你可以依赖skew转换和伪元素.这里的技巧是你不必根据条纹定义宽度,但条纹将遵循你将定义的宽度,因此它将更容易处理.

li {
  display: inline-block;
  width: calc( 20px * 3); /* it's only 20px * N */
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  position:relative;
  z-index:0;
  overflow:hidden
}
li::before {
  content:"";
  position:absolute;
  top:0;
  bottom:0;
  left:0;
  width:400%;
  /*we keep 0deg in the gradient*/
  background-image: repeating-linear-gradient(90deg, transparent, transparent 10px, black 10px, black 20px);
  transform:skewX(30deg);
  transform-origin:bottom left;
  animation: loading-slide 4s linear infinite;
}

@keyframes loading-slide {
  to {
    transform: translateX(-50%) skewX(30deg);
  }
}

.alt li {
  width: calc( 20px * 6);
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

如您所见,我们保持垂直渐变,我们根据渐变的宽度定义元素的宽度.我们使伪元素足够大,并在其上应用翻译.你唯一需要调整的是控制度数的偏斜变换.

使用这种方法,您将获得更好的性能,因为您将动画转换而不是background-size.

更多例子:

li {
  display: inline-block;
  width: calc( 20px * var(--n,3)); /* it's only 20px * N */
  height: 50px;
  margin-bottom:10px;
  background-color: blue;
  position:relative;
  z-index:0;
  overflow:hidden
}
li::before {
  content:"";
  position:absolute;
  top:0;
  bottom:0;
  left:-400%;
  right:-800%;
  /*we keep 0deg in the gradient*/
  background-image: repeating-linear-gradient(90deg, transparent, transparent 10px, black 10px, black 20px);
  transform:skewX(var(--d,30deg));
  animation: loading-slide 12s linear infinite;
}

@keyframes loading-slide {
  to {
    transform: translateX(-50%) skewX(var(--d,30deg));
  }
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>test</li><li>test</li>
</ul>

<ul style="--n:6;--d:45deg">
  <li>test</li><li>test</li>
</ul>
<ul style="--n:8;--d:-70deg">
  <li>test</li><li>test</li>
</ul>
<ul style="--n:8;--d:30deg">
  <li>test</li><li>test</li>
</ul>
Run Code Online (Sandbox Code Playgroud)