【问题标题】:simplify this css svg animation简化这个 css svg 动画
【发布时间】:2020-06-16 20:42:44
【问题描述】:

我正在努力让矩形改变颜色。每个矩形都会延迟 0.1 秒。

假设我想要更多的矩形或路径,我该如何简化代码?我认为可以使用 scss 来简化它,但是使用 CSS 呢?有没有比我做的更聪明的方法?

#svg rect:nth-child(1) {
  animation: ani 1.8s linear infinite;
  animation-delay: 0.1s;
}

#svg rect:nth-child(1):hover {
  animation-play-state: paused;
}

#svg rect:nth-child(2) {
  animation: ani 1.8s linear infinite;
  animation-delay: 0.2s;
}

#svg rect:nth-child(2):hover {
  animation-play-state: paused;
}

#svg rect:nth-child(3) {
  animation: ani 1.8s linear infinite;
  animation-delay: 0.3s;
}

#svg rect:nth-child(3):hover {
  animation-play-state: paused;
}

#svg rect:nth-child(4) {
  animation: ani 1.8s linear infinite;
  animation-delay: 0.4s;
}

#svg rect:nth-child(4):hover {
  animation-play-state: paused;
}

#svg rect:nth-child(5) {
  animation: ani 1.8s linear infinite;
  animation-delay: 0.5s;
}

#svg rect:nth-child(5):hover {
  animation-play-state: paused;
}

@keyframes ani {
  0% {
    fill: #0057B8;
  }
  20% {
    fill: #F11E4A;
  }
  40% {
    fill: #F8A527;
  }
  60% {
    fill: #266D7F;
  }
  80% {
    fill: #82A;
  }
  100% {
    fill: #0057B8;
  }
}
<svg id="svg" width="401" height="275" viewBox="0 0 401 275" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="401" height="275" fill="white"/>
<rect x="50" y="91" width="57" height="57" fill="#C4C4C4"/>
<rect x="118" y="91" width="57" height="57" fill="#C4C4C4"/>
<rect x="186" y="91" width="57" height="57" fill="#C4C4C4"/>
<rect x="254" y="91" width="57" height="57" fill="#C4C4C4"/>
</svg>

【问题讨论】:

标签: html css svg css-animations


【解决方案1】:

对于:hover 和基础rect 动画复制,它们可以各自重构为自己的块。

#svg rect {
  --animation-delay: 0.1s;
  animation: ani 1.8s linear infinite var(--animation-delay);
}

#svg rect:hover {
  animation-play-state: paused;
}

我会将动画延迟存储在自定义属性中,并将其添加到单独的动画调用中。

#svg rect {
  --animation-delay: 0.1s;
  animation: ani 1.8s linear infinite var(--animation-delay);
}

现在您可以稍后在必要时覆盖延迟,例如:

#svg rect:nth-child(3) { --animation-delay: 0.2s; }

延迟将针对该孩子的动画自动更新。

这是完整的代码:

#svg rect {
  --animation-delay: 0.1s;
  animation: ani 1.8s linear infinite var(--animation-delay);
}

#svg rect:hover {
  animation-play-state: paused;
}

<!-- No way to shorten this in pure CSS ? -->

#svg rect:nth-child(2) { --animation-delay: 0.2s; }
#svg rect:nth-child(3) { --animation-delay: 0.3s; }
#svg rect:nth-child(4) { --animation-delay: 0.4s; }
#svg rect:nth-child(5) { --animation-delay: 0.5s; }

@keyframes ani {
  0% {
    fill: #0057B8;
  }

  20% {
    fill: #F11E4A;
  }

  40% {
    fill: #F8A527;
  }

  60% {
    fill: #266D7F;
  }

  80% {
    fill: #82A;
  }

  100% {
    fill: #0057B8;
  }
}
<svg id="svg" width="401" height="275" viewBox="0 0 401 275" fill="none" xmlns="http://www.w3.org/2000/svg">
  <rect width="401" height="275" fill="white" />
  <rect x="50" y="91" width="57" height="57" fill="#C4C4C4" />
  <rect x="118" y="91" width="57" height="57" fill="#C4C4C4" />
  <rect x="186" y="91" width="57" height="57" fill="#C4C4C4" />
  <rect x="254" y="91" width="57" height="57" fill="#C4C4C4" />
</svg>

jsFiddle

【讨论】:

【解决方案2】:

您的所有:hover 效果都是相同的,您的animation 属性也是如此,因此您可以将它们简化为一个规则:

#svg rect {
    animation: ani 1.8s linear infinite;
}

#svg rect:hover {
    animation-play-state: paused;
}

这已经大大减少了线条,因为动画本身会延迟你的方法是好的。

【讨论】:

  • 谢谢!有没有更好的方法来处理 rect:nth-child(N) ?假设 20 个矩形..
  • 如果您可以使用 css 变量,您可以使用这些变量并设置 animation-delay: var(--delay); 并在 rect 元素本身上设置延迟:&lt;rect style="--delay: 0.1s" ...&gt; 但否则不能,遗憾的是您不能使用来自'nth-child' 来计算属性。
【解决方案3】:

如果您对 CSS 解决方案感兴趣,可以执行以下操作。这是一个有点不同的动画,但您可以通过保持相同的代码轻松对其进行缩放。

诀窍是为所有框设置相同的渐变动画以模拟颜色变化。请注意我如何使伪元素相对于 .box 而不是子元素具有相同的层

.box {
   display:inline-flex;
   margin:5px;
   padding:50px 20px;
   position:relative;
   background:right/800% 100%;
   background-image:linear-gradient(to left,#0057B8,#F11E4A,#F8A527,#266D7F,#82A,#0057B8);
   animation: ani 1.8s linear infinite;
}
.box > div {
  margin:5px;
  height:55px;
  width:55px;
  background-image:inherit;
  -webkit-mask: linear-gradient(#fff,#fff);
          mask: linear-gradient(#fff,#fff);
}
.box > div:before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background: right/1000% 100%;
  background-image:inherit;
  animation: ani 2s linear infinite;
}

.box > div:hover:before {
  animation-play-state:paused;
}

@keyframes ani {
  100% {
    background-position:left;
  }
}
<div class="box">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
<br>
<div class="box">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

【讨论】:

    猜你喜欢
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    • 2015-08-26
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多