动画

动画

CSS animation

.element {
  animation: pulse 5s infinite;
}

@keyframes pulse {
  0% {
    background-color: #001F3F;
  }
  100% {
    background-color: #FF4136;
  }
}

@keyframes 中,0% 代表动画的开始,100% 代表动画的结束。animation 可用的子属性:

.element {
  animation-name: stretch;
  animation-duration: 1.5s; 
  animation-timing-function: ease-out; 
  animation-delay: 0s;
  animation-direction: alternate;
  animation-iteration-count: infinite;
  animation-fill-mode: none;
  animation-play-state: running; 
}

CSS transition

transition 控制的是从一种状态/阶段/样式,转变为另外一种状态/阶段/样式,animation 控制的是整个动画的每一帧。

.example {
    transition: [transition-property] [transition-duration] [transition-timing-function] [transition-delay];
}

鼠标悬浮在 div 的时候,转变 backgroundpadding 的状态:

div {
  transition: all 0.5s ease;
  background: red;
  padding: 10px;
}

div:hover {
  background: green;
  padding: 20px;
}

或者你也可以使用逗号单独指定每一个属性的动作:

div {
  transition: background 0.2s ease,
              padding 0.8s linear;
}

如何触发 Transition

  • 使用伪类 :hover:focus:active
  • 添加或移除 class
.button {
  background-color: #33ae74;
  transition: background-color 0.5s ease-out;
}

.button.is-active {
  background-color: #1ce;
}
const button = document.querySelector('.button')
button.addEventListener('click', _ => button.classList.toggle('is-active'))

JavaScript 动画

setInterval

示例代码如下:

let start = Date.now(); // remember start time

let timer = setInterval(function() {
  // how much time passed from the start?
  let timePassed = Date.now() - start;

  if (timePassed >= 2000) {
    clearInterval(timer); // finish the animation after 2 seconds
    return;
  }

  // draw the animation at the moment timePassed
  draw(timePassed);

}, 20);

// as timePassed goes from 0 to 2000
// left gets values from 0px to 400px
function draw(timePassed) {
  train.style.left = timePassed / 5 + 'px';
}

requestAnimationFrame

function animate({timing, draw, duration}) {

  let start = performance.now();

  requestAnimationFrame(function animate(time) {
    // timeFraction goes from 0 to 1
    let timeFraction = (time - start) / duration;
    if (timeFraction > 1) timeFraction = 1;

    // calculate the current animation state
    let progress = timing(timeFraction)

    draw(progress); // draw it

    if (timeFraction < 1) {
      requestAnimationFrame(animate);
    }

  });
}

参考