Как изменить функцию анимации во время анимации? - PullRequest
3 голосов
/ 22 февраля 2020

У меня есть анимация, в которой я хочу, чтобы элемент (текст) свернулся с ease-out и развернулся с ease-in в середине анимации.

Так что в основном я хочу изменить время анимации -функция в середине анимации - как мне добиться этого желательно без лишних JS?

Я думал о 2 последовательных анимациях, но, возможно, есть какой-то более простой способ?

var animatingNow = false;

function toggleRolling() {
  if (animatingNow) {
    return;
  }
  animatingNow = true;
  document.querySelector('.roller').classList.add('rolling');
  setTimeout(function() {
    animating = false;
    document.querySelector('.roller').classList.remove('rolling')
  }, 2120);

}
* {
  box-sizing: border-box;
}

body {
  font-family: 'Open Sans';
  font-size: 14px;
  padding: 30px 20px;
}

.wrapper {
  overflow: hidden;
  width: 100%;
  height: 40px;
  background: #444;
  border-radius: 5px;
  position: relative;
}

.wrapper .roller {
  position: absolute;
  right: 0;
  top: 0;
  height: 500%;
  display: flex;
  padding-right: 16px;
  flex-direction: column;
  user-select: none;
  color: white;
  opacity: 0.7;
  justify-content: space-between;
  transition: opacity 0.4s;
}

.wrapper .roller:hover,
.wrapper .roller.rolling {
  opacity: 1;
  --last-step-opacity: 0.7;
}

.wrapper .roller:hover {
  --last-step-opacity: 1;
}

.wrapper .roller.rolling {
  animation: roll 2.12s ease-out;
}

.wrapper .roller>span {
  height: 20%;
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

@keyframes roll {
  0% {
    transform: translateY(0);
    opacity: 1;
  }
  10% {
    transform: translateY(0);
    opacity: 0;
  }
  11% {
    transform: translateY(-20%);
    opacity: 0;
  }
  12% {
    opacity: 1;
  }
  30%,
  70% {
    transform: translateY(-40%);
    opacity: 1;
  }
  88% {
    transform: translateY(-60%);
    opacity: 1;
  }
  89% {
    opacity: 0;
  }
  90% {
    transform: translateY(-80%);
  }
  100% {
    opacity: 0.7;
    opacity: var(--last-step-opacity);
    transform: translateY(-80%);
  }
}
<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">
<div onclick="toggleRolling()" class="wrapper">
  <div class="roller">
    <span> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" > <path fill-rule="evenodd" clip-rule="evenodd" d="M12 12H14C15.1046 12 16 11.1046 16 10V2C16 0.895431 15.1046 0 14 0H6C4.89543 0 4 0.895431 4 2V4H2C0.895431 4 0 4.89543 0 6V14C0 15.1046 0.895431 16 2 16H10C11.1046 16 12 15.1046 12 14V12ZM14 2H6V4H10C11.1046 4 12 4.89543 12 6V10H14V2ZM10 6H2L2 14H10V6Z" fill="currentColor" /> </svg></span>
    <span>Copied!</span>
    <span> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" > <path fill-rule="evenodd" clip-rule="evenodd" d="M12 12H14C15.1046 12 16 11.1046 16 10V2C16 0.895431 15.1046 0 14 0H6C4.89543 0 4 0.895431 4 2V4H2C0.895431 4 0 4.89543 0 6V14C0 15.1046 0.895431 16 2 16H10C11.1046 16 12 15.1046 12 14V12ZM14 2H6V4H10C11.1046 4 12 4.89543 12 6V10H14V2ZM10 6H2L2 14H10V6Z" fill="currentColor" /> </svg></span>
  </div>
</div>

1 Ответ

1 голос
/ 22 февраля 2020

Вы можете решить это без animation, но используя 2 разных класса: .rolling-in и .rolling-out. Также только 1 значок. Затем будут переходы для раскатывания и раскатывания.

function toggleRolling(el) {
  el.classList.add('rolling-in');
  setTimeout(function(){
    el.classList.add('rolling-out')
  },1000)
  setTimeout(function(){
    el.classList.remove('rolling-in', 'rolling-out')
  },2000)
}
* {
  box-sizing: border-box;
}

body {
  font-family: 'Open Sans';
  font-size: 14px;
  padding: 30px 20px;
}

.wrapper {
  overflow: hidden;
  width: 100%;
  height: 40px;
  background: #444;
  border-radius: 5px;
  position: relative;
}

.wrapper .roller {
  position: absolute;
  right: 0;
  top: 0;
  height: 500%;
  display: flex;
  padding-right: 16px;
  flex-direction: column;
  user-select: none;
  color: white;
  opacity: 0.7;
  justify-content: space-between;
  transition: opacity 0.4s;
}

.wrapper .roller:hover,
.wrapper .roller.rolling {
  opacity: 1;
  --last-step-opacity: 0.7;
}

.wrapper .roller:hover {
  --last-step-opacity: 1;
}

.wrapper .roller > span {
  height: 20%;
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

.wrapper.rolling-in {
  pointer-events: none;
}

.rolling-in .icon {
  opacity: 0;
  pointer-events: none;
  transition: 0.24s ease-out;
}

.rolling-in .copied {
  transform: translateY(-400%);
  transition: 0.46s 0.1s ease-out;
}

.rolling-in.rolling-out .icon {
  opacity: 1;
  pointer-events: none;
  transition: 0.24s 0.34s ease-out;
}

.rolling-in.rolling-out .copied {
  transition: 0.46s 0.1s ease-in;
  transform: translateY(-800%);
}
<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">
<div onclick="toggleRolling(this)" class="wrapper">
  <div class="roller">
    <span class="icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" > <path fill-rule="evenodd" clip-rule="evenodd" d="M12 12H14C15.1046 12 16 11.1046 16 10V2C16 0.895431 15.1046 0 14 0H6C4.89543 0 4 0.895431 4 2V4H2C0.895431 4 0 4.89543 0 6V14C0 15.1046 0.895431 16 2 16H10C11.1046 16 12 15.1046 12 14V12ZM14 2H6V4H10C11.1046 4 12 4.89543 12 6V10H14V2ZM10 6H2L2 14H10V6Z" fill="currentColor" /></svg></span>
    <span class="copied">Copied!</span>
  </div>
</div>

Я также добавил pointer-events: none в оболочку, чтобы не вызывать двойной щелчок при анимации. Итак, классы добавляются к .wrapper, а не .roller сейчас.

...