Обратная анимация ключевых кадров CSS - PullRequest
2 голосов
/ 10 мая 2019

Я написал анимацию CSS, используя ключевые кадры для пути SVG

path {
  animation: anim 1s linear;
  animation-fill-mode: forwards;
}

@keyframes anim {
  50% {
    d: path('M20 20 L 20 20');
  }
  100% {
    d: path('M10 10 L 30 30');
  }
}
<path class="top" d="M10 10 L 30 10" stroke-width="2" stroke="black" fill="transparent" />

Источник

Если вы нажмете на SVG, вы увидите анимацию в действии.Теперь, если вы нажмете еще раз, я хочу, чтобы анимация была в исходном состоянии.Я пытался добавить

transition: all 1s ease-out;

и

animation-direction: alternate;

Но анимация не вернулась в исходное состояние.

Итак, вопрос в том, как я могуоживить назад?

1 Ответ

4 голосов
/ 10 мая 2019

С переходом вы можете легко сделать это, но анимация будет немного другой:

const svg = document.querySelector('svg');

svg.addEventListener('click', () => {
  svg.classList.toggle('close');
});
svg {
  border: 1px solid blue;
}

svg path {
  transition: 0.2s all linear;
}

svg.close path.top {
  d: path('M10 10 L 30 30');
}

svg.close path.middle {
  d: path('M20 20 L 20 20');
}

svg.close path.bottom {
  d: path('M10 30 L 30 10');
}
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">

  <path class="top" d="M10 10 L 30 10" stroke-width="2" stroke="black" fill="transparent"/>
  <path class="middle" d="M10 20 L 30 20" stroke-width="2" stroke="black" fill="transparent"/>
  <path class="bottom" d="M10 30 L 30 30" stroke-width="2" stroke="black" fill="transparent"/>
</svg>

Другая идея заключается в том, чтобы полагаться на animationiteration, где нужно уловить анимацию infinite и останавливать ее на каждой итерации.

const svg = document.querySelector('svg');

const path = document.querySelector('svg path');

svg.addEventListener('click', () => {
  svg.classList.toggle('close');
});


path.addEventListener('animationiteration', () =>{
 svg.classList.toggle('close');
});
svg {
  border: 1px solid blue;
}


path.top {
  animation: close-top 0.2s linear infinite alternate;
}

path.middle {
  animation: close-middle 0.2s linear infinite alternate;
}

path.bottom {
  animation: close-bottom 0.2s linear infinite alternate;
}

svg:not(.close) path {
 animation-play-state: paused;
}

svg.close path {
 animation-play-state: running;
}

@keyframes close-top {
  50% {
    d: path('M20 20 L 20 20');
  }
  100% {
    d: path('M10 10 L 30 30');
  }
}

@keyframes close-middle {
  to {
    d: path('M20 20 L 20 20');
  }
}

@keyframes close-bottom {
  50% {
    d: path('M20 20 L 20 20');
  }
  100% {
    d: path('M10 30 L 30 10');
  }
}
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">

  <path class="top" d="M10 10 L 30 10" stroke-width="2" stroke="black" fill="transparent"/>
  <path class="middle" d="M10 20 L 30 20" stroke-width="2" stroke="black" fill="transparent"/>
  <path class="bottom" d="M10 30 L 30 30" stroke-width="2" stroke="black" fill="transparent"/>
</svg>
...