CSS @keyframe Animation Удаление всей кнопки вместо только границы - PullRequest
1 голос
/ 20 октября 2019

У меня есть анимация ключевого кадра CSS, которая очерчивает границу кнопки. Однако, когда я пытаюсь повернуть анимацию при выключенной мыши, она удаляет тень от вставки вместо градиента.

Как вы можете видеть ниже, я попытался установить границу и фон снова в mouseLeaveAnimationClass. Это тоже не решает проблему. Есть ли элегантное решение этой проблемы?

var els = document.querySelectorAll('.get-started');
for (var i = 0; i < els.length; i++) {
  els[i].addEventListener('mouseleave', function(e) {
    e.target.classList.add('mouseleaveAnimationClass');
  });
  els[i].addEventListener('mouseenter', function(e) {
    e.target.classList.remove('mouseleaveAnimationClass');
  });
}
 body {

   background-color: black;

 }

#button {
  display: flex;
  font-size: 2.5rem;
  color: white;
  align-items: center;
  justify-content: center;
  width: 250px;
  height: 75px;
  position: relative;
  top: -30%;
  left: calc(50% - 125px);
}

.get-started {
  --borderWidth: 5px;
  position: relative;
  border-radius: var(--borderWidth);
  background-color: #8551FF;
  box-shadow: inset 0 0 0 5px white;
  z-index: 1;
}

.get-started:after {
  content: '';
  position: absolute;
}

.get-started:hover:after {
  background: linear-gradient(60deg, #f79533, #f37055, #ef4e7b, #a166ab, #5073b8, #1098ad, #07b39b, #6fba82);
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border-radius: 2px;
  background-size: 300% 300%;
  animation: frame-enter 1s forwards ease-in-out reverse, gradient-animation 4s ease-in-out infinite;
}

.get-started.mouseleaveAnimationClass {
  background: linear-gradient(60deg, #f79533, #f37055, #ef4e7b, #a166ab, #5073b8, #1098ad, #07b39b, #6fba82);
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border-radius: 2px;
  background-size: 300% 300%;
  animation: frame-enter 1s forwards ease-in-out;
}


/* motion */

@keyframes gradient-animation {
  0% {
    background-position: 15% 0%;
  }
  50% {
    background-position: 85% 100%;
  }
  100% {
    background-position: 15% 0%;
  }
}

@keyframes frame-enter {
  0% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 5px, calc(100% - 5px) 5px, calc(100% - 5px) calc(100% - 5px), 5px calc(100% - 5px), 5px 100%, 100% 100%, 100% 0%, 0% 0%);
  }
  25% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 5px, calc(100% - 5px) 5px, calc(100% - 5px) calc(100% - 5px), calc(100% - 5px) calc(100% - 5px), calc(100% - 5px) 100%, 100% 100%, 100% 0%, 0% 0%);
  }
  50% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, 100% 0%, 0% 0%);
  }
  75% {
    -webkit-clip-path: polygon(0% 100%, 5px 100%, 5px 5px, 5px 5px, 5px 5px, 5px 5px, 5px 5px, 5px 5px, 5px 0%, 0% 0%);
  }
  100% {
    -webkit-clip-path: polygon(0% 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 0% 100%);
  }
}
<div class="get-started" id="button">Get Started</div>

Пример запуска

1 Ответ

2 голосов
/ 20 октября 2019

В исходной задаче правило .get-started.mouseleaveAnimationClass { применяется к самому элементу, а не к псевдоэлементу ::after, и поэтому элемент обрезается. Однако это не решит вашу главную проблему - обратную анимацию.

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

Только при первом наведении курсора класс .ready добавляется к кнопке,Это включает анимацию frame-leave без ее запуска. Всякий раз, когда вы :hover используете элемент, применяется анимация frame-enter, и как только вы покидаете элемент, снова вызывается frame-leave.

Примечания:

  1. frame-enter и frame-leave - это одна и та же анимация. Использование другого имени позволяет нам заменить их.
  2. Когда вы входите, а затем уходите в середине анимации, она будет перепрыгивать с анимации входа на выход.

var els = document.querySelectorAll('.get-started');
for (var i = 0; i < els.length; i++) {
  els[i].addEventListener('mouseenter', function(e) {
    e.target.classList.add('ready');
  }, { once: true });
}
#button {
  display: flex;
  font-size: 2.5rem;
  color: white;
  align-items: center;
  justify-content: center;
  width: 250px;
  height: 75px;
  position: relative;
  top: -30%;
  left: calc(50% - 125px);
}

.get-started {
  --borderWidth: 5px;
  position: relative;
  border-radius: var(--borderWidth);
  background-color: #8551FF;
  box-shadow: inset 0 0 0 5px white;
  z-index: 1;
}

.get-started::after {
  content: '';
  position: absolute;
  background: linear-gradient(60deg, #f79533, #f37055, #ef4e7b, #a166ab, #5073b8, #1098ad, #07b39b, #6fba82);
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border-radius: 2px;
  background-size: 300% 300%;
  clip-path: polygon(0% 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 0% 100%);
}

.get-started.ready::after {
  animation: frame-leave 1s forwards ease-in-out, gradient-animation 4s ease-in-out infinite;
}

.get-started.ready:hover::after {
  animation: frame-enter 1s forwards ease-in-out reverse, gradient-animation 4s ease-in-out infinite;
}


/* motion */

@keyframes gradient-animation {
  0% {
    background-position: 15% 0%;
  }
  50% {
    background-position: 85% 100%;
  }
  100% {
    background-position: 15% 0%;
  }
}

@keyframes frame-enter {
  0% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 5px, calc(100% - 5px) 5px, calc(100% - 5px) calc(100% - 5px), 5px calc(100% - 5px), 5px 100%, 100% 100%, 100% 0%, 0% 0%);
  }
  25% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 5px, calc(100% - 5px) 5px, calc(100% - 5px) calc(100% - 5px), calc(100% - 5px) calc(100% - 5px), calc(100% - 5px) 100%, 100% 100%, 100% 0%, 0% 0%);
  }
  50% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, 100% 0%, 0% 0%);
  }
  75% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 5px, 5px 5px, 5px 5px, 5px 5px, 5px 5px, 5px 5px, 5px 0%, 0% 0%);
  }
  100% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 0% 100%);
  }
}

@keyframes frame-leave {
  0% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 5px, calc(100% - 5px) 5px, calc(100% - 5px) calc(100% - 5px), 5px calc(100% - 5px), 5px 100%, 100% 100%, 100% 0%, 0% 0%);
  }
  25% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 5px, calc(100% - 5px) 5px, calc(100% - 5px) calc(100% - 5px), calc(100% - 5px) calc(100% - 5px), calc(100% - 5px) 100%, 100% 100%, 100% 0%, 0% 0%);
  }
  50% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, 100% 0%, 0% 0%);
  }
  75% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 5px, 5px 5px, 5px 5px, 5px 5px, 5px 5px, 5px 5px, 5px 0%, 0% 0%);
  }
  100% {
    clip-path: polygon(0% 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 0% 100%);
  }
}
<div class="get-started" id="button">Get Started</div>
...