使用 CSS 线性渐变创建无缝动画

时间:2021-02-10 17:48:45

标签: css css-animations linear-gradients css-gradients repeating-linear-gradient

div {
  border-radius: 2rem;
  width: 10rem;
  height: 10rem;
  background-color: #0dd;
  background-image: 
    linear-gradient( 
      -45deg, 
      rgba( 0,0,0,0.125 ), transparent, rgba( 0,0,0,0.125 ), transparent
    );  
}

div {
  animation-name: diagonal_move;
  animation-duration: 6s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
@keyframes diagonal_move {
  0% {
    background-position: 0rem 0rem;
  }
  100% {
    background-position: 10rem 10rem;
  }
}
<html>
  <head>
    <style>
      * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
      }
      html, body {
        height: 100%;
      }
      body {
        display: flex;
        justify-content: center;
        align-items: center;
      }
    </style>
  </head>

  <body>
    <div></div>
  </body>
</html>

当上面的线性渐变动画时,可以清楚地看到渐变的边缘 - 而不是与周围环境无缝融合。

试图隐藏边缘的解决方案是在顶部叠加额外的渐变:

div {
  border-radius: 2rem;
  width: 10rem;
  height: 10rem;
  background-color: #0dd;
  background-image: 
    linear-gradient( #0dd, transparent, transparent, transparent, #0dd ),
    linear-gradient( 90deg, #0dd, transparent, transparent, transparent, #0dd ),
    linear-gradient( 
      -45deg, 
      rgba( 0,0,0,0.125 ), transparent, rgba( 0,0,0,0.125 ), transparent
    ); 
}

div {
  animation-name: diagonal_move;
  animation-duration: 6s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
@keyframes diagonal_move {
  0% {
    background-position: 0rem 0rem;
  }
  100% {
    background-position: 10rem 10rem;
  }
}
<html>
  <head>
    <style>
      * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
      }
      html, body {
        height: 100%;
      }
      body {
        display: flex;
        justify-content: center;
        align-items: center;
      }
    </style>
  </head>

  <body>
    <div></div>
  </body>
</html>

这种方法的问题在于它隐藏了大部分原始渐变和接缝。它还可以在接缝处创建亮线。

那么有没有办法在渐变结束时翻转或镜像渐变以创建无缝图案?或者原始渐变可能更大并缩小以产生无缝图案的错觉。如何实施?

2 个答案:

答案 0 :(得分:1)

您的渐变由 3 个部分组成(在 4 个参考点/颜色定义之间),这会创建一种“不对称”结构,因为末尾的颜色与开头的颜色不同。如果添加另一个参考点/颜色(与第一个相同),渐变在开始和结束以及正方形的其他两个角具有相同的颜色,因此动画效果流畅:

div {
  border-radius: 2rem;
  width: 10rem;
  height: 10rem;
  background-color: #0dd;
  background-image: 
    linear-gradient( 
      -45deg, 
      rgba( 0,0,0,0.125 ), transparent, rgba( 0,0,0,0.125 ), transparent, rgba( 0,0,0,0.125 )
    );  
}

div {
  animation-name: diagonal_move;
  animation-duration: 6s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
@keyframes diagonal_move {
  0% {
    background-position: 0rem 0rem;
  }
  100% {
    background-position: 10rem 10rem;
  }
}
<html>
  <head>
    <style>
      * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
      }
      html, body {
        height: 100%;
      }
      body {
        display: flex;
        justify-content: center;
        align-items: center;
      }
    </style>
  </head>

  <body>
    <div></div>
  </body>
</html>

答案 1 :(得分:1)

在这种情况下,最好考虑比元素大两倍的重复梯度,这样您就不必为 background-position 中的特定值而烦恼:

.box {
  border-radius: 2rem;
  width: 10rem;
  height: 10rem;
  background-color:;
  background: 
    repeating-linear-gradient( 
      -45deg, 
      rgba( 0,0,0,0.125 ), transparent, rgba( 0,0,0,0.125 ) 25%
    ) bottom right/200% 200%
     #0dd;  
  animation: diagonal_move 6s linear infinite;
}

@keyframes diagonal_move {
  100% {
    background-position: top left;
  }
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin:0;
}
<div class="box"></div>

有关值和计算的更多详细信息:Using percentage values with background-position on a linear-gradient

相关问题