упростить эту css SVG анимацию - PullRequest
0 голосов
/ 04 марта 2020

Я работаю над этим, чтобы иметь прямоугольник для изменения цвета. Каждый прямоугольник будет меняться с задержкой 0,1 с.

Допустим, я хочу иметь больше прямоугольников или путей, как я могу упростить код? Я думаю, что это можно упростить с помощью s css, но как насчет использования 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>

Ответы [ 3 ]

3 голосов
/ 04 марта 2020

Для дублирования анимации :hover и base 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 голосов
/ 04 марта 2020

Все ваши :hover эффекты одинаковы, как и ваши animation свойства, так что вы можете упростить их до одного правила для каждого:

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

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

, которое уже значительно уменьшило бы строки, для анимация задерживает себя, ваш метод в порядке.

0 голосов
/ 04 марта 2020

Если вы заинтересованы в решении 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>
...