如何使用线性渐变创建无限的背景图案动画? [英] How to create an infinite background pattern animation using linear-gradient?

查看:58
本文介绍了如何使用线性渐变创建无限的背景图案动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to create an animated repeating-pattern (diagonal stripes sliding horizontally), as placeholder for a loading block (li in this case).

如何使动画平滑/连续,以使幻觉图案无限滑动?

  • 如何计算元素 width 以便图案连续?(条纹不应看起来破碎/打断).
  • 如何使它看起来像不是在重新启动而是无限滑动地循环?(100%的帧应无任何毛刺地传递到0%的帧)
  • How to calculate the element width so that the pattern is continuous? (stripes shouldn't look broken/interrupted).
  • How to make it loop looking like it is not restarting but rather sliding infinitely? (the 100% frame should pass to the 0% frame without any glitch)

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

The goal is to have a class I can add to any block and will visually look like loading/processing.

注意:没有JS;纯CSS.

Note: no JS; pure 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% }
  }

<ul>
    <li>test
    <li>test
</ul>

推荐答案

正确的公式应为(20px/cos(45deg))* N .然后,您可以将 background-size 设置为 200%100%(比元素大两倍),然后从左到右对其进行动画处理:

The correct formula should be (20px / cos(45deg)) * N. Then you can make the background-size to be 200% 100% (twice bigger than the element) and you animate it from left to right:

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);
}

<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

您可以考虑任意程度,并根据需要调整公式.(20px/cos(90deg-| Xdeg |))* N ,其中 X -90deg 90deg

You can consider any degree and adjust the formula as needed. (20px / cos(90deg - |Xdeg|)) * N with X between -90deg and 90deg

具有 -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;
}

<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

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;
}

<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

具有 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;
}

<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

您可以清楚地识别出 X = +/-90deg (垂直条纹)的琐碎情况,我们将得到 cos(0)= 1 ,因此公式为 20px * N .同样,当 X = 0 (水平条纹)时,我们将具有 cos(90deg)= 0 ,并且由于没有垂直模式(公式不再定义,因此任何宽度都可以))

You can clearly identify the trivial case where X=+/-90deg (vertical stripes) and we will have cos(0)=1 thus the formula will be 20px * N. Also when X=0 (horizontal stripes) we will have cos(90deg) = 0 and any width will work since there is no vertical pattern (the formula is no more defined)

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);
}

<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

[-90deg,90deg] 之外的值如何?

What about value outside [-90deg,90deg]?

上面的范围已经覆盖了 180deg ,并且由于我们正在处理对称的事物,因此所有值都可以在该范围内表示.

The above range already cover 180deg and since we are dealing with something symetric, all the value can be represented inside that range.

示例: 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;
  }
}

<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

示例: -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;
  }
}

<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

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

basically we add/remove 180deg until we get inside [-90deg,90deg] in order to be able to apply the formula.

检查此答案以获取有关 background-size / background-position 的工作方式的更多详细信息:

Check this answer for more details about how background-size/background-position works: Using percentage values with background-position on a linear-gradient

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

Here is a complete different idea where you can rely on skew transformation and pseudo element. The trick here is that you don't have to define the width based on the stripes but the stripes will follow the width you will define so it will be easier to handle.

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);
}

<ul>
  <li>test</li><li>test</li>
</ul>

<ul class="alt">
  <li>test</li><li>test</li>
</ul>

如您所见,我们保持垂直渐变,我们根据渐变的宽度定义元素的宽度.我们使伪元素足够大,然后对其进行翻译.您唯一需要调整的是偏斜变换以控制度数.

As you can see, we keep a vertical gradient, we define the width of the element based on the width of the gradient. We make the pseudo element big enough and we apply a translation on it. The only thing you need to adjust is the skew transformation to control the degree.

使用这种方法,由于您将对转换进行动画处理,而不是使用 background-size .

With this approach you will also have better performance since you will animate transform instead of 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));
  }
}

<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>

这篇关于如何使用线性渐变创建无限的背景图案动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆