참치에게 브라우저상을 기분 좋게 수영 받기 위한 애니메이션 선정



브라우저 위를 참치에 헤엄치고 싶을 때,
기분 좋게 움직일 수 있는 것은 어떤 구현인가.
CSS와 JS의 애니메이션 라이브러리를 비교해 선택해 가고 싶습니다.

CSS 또는 JS를 선택하는 기준



가벼운 애니메이션이라면 CSS



호버나 요소의 페이드 인 아웃, 단순한 이동이나 회전의 경우,
CSS의 transition이나 animation으로 하는 편이,
구현이 편한 데다 동작이 가벼운 경우가 많습니다. (특히 스마트 폰에서)

복잡한 애니메이션이라면 JS



복잡한 애니메이션이 필요할 때,
타임라인을 따라 애니메이션을 구현하는 경우 등
JS로 쓰는 것이 유연성이 높고 읽기 쉽습니다.

참치 애니메이션은?



참치 애니메이션을 구현하는 경우,
그런 정석은 통용하지 않기 때문에, 감각적으로 참치가 살아있는 것처럼 보이는 것을 선택해 갈 필요가 있습니다.

비교 방법



모든 애니메이션을 동시에 재생하여 비교,
가장 확실히 오는 것 (주관)을 채용합니다.

동시에 재생할 때, 각각의 애니메이션을 루프로 구현하는 것도 가능합니다만,
한번 어긋나기 시작하는 전체적으로 흩어져 버리므로,

동시에 재생 => Promise에서 모든 끝을 기다리는 => 동시에 재생

의 흐름으로, 애니메이션의 비교를 하기 쉬운 형태로 구현합니다.

setInterval로 적당한 시간을 비워도 비슷한 구현은 할 수 있습니다만,
어쩐지 저기 때문에 채용하지 않았습니다.

구현



Promise에서 끝을 기다리는 루프


const infiniteTuna = (animationPromises) => {
  Promise.all(animationPromises.map(p => p()))
    .then(() => {
      infiniteTuna(animationPromises)
    })
}

infiniteTuna([
  cssPromise,
  tweenPromise,
  velocityPromise,
  animePromise
])

각 애니메이션에서 Promise를 반환하면,Promise.all 에 건네주어 애니메이션의 종료를 기다려 루프 시킵니다.

CSS 애니메이션


.tuna.is-active {
  animation: anime 1.2s cubic-bezier(0.645, 0.045, 0.355, 1); /* easeInOutCubic */
}

@keyframes anime {
  0% {
    transform: translate3d(100vw, 0, 0); /* 表示領域の幅(右の画面外) */
  }
  100% {
    transform: translate3d(-100%, 0, 0); /* 自分の幅(左の画面外) */
  }
}
const cssPromise = () => {
  return new Promise(resolve => {
    const el = document.getElementById('css')
    const activeClass = 'is-active'

    const onAnimationEnd = () => {
      el.removeEventListener('animationend', onAnimationEnd)
      el.classList.remove(activeClass)
      setTimeout(() => resolve(), 0) // クラスのremove => addを意図的に遅らせる
    }

    el.addEventListener('animationend', onAnimationEnd)
    el.classList.add(activeClass)
  })
}

클래스를 붙여 애니메이션 시키고, 끝나면 클래스를 제외합니다.
본래는 이벤트 리스너에게 webkit도 지정해야 합니다만,
그런 사소한 것은 참치 앞에서는 무력하기 때문에 신경 쓰지 않기로 합니다.

TweenMax


const tweenPromise = () => {
  return new Promise(resolve => {
    const el = document.getElementById('tween')

    TweenMax.fromTo(el, duration / 1000, {
      x: windowWidth
    }, {
      x: -elementWidth,
      ease: Power2.easeInOut,
      onComplete: () => resolve()
    })
  })
}

기능이 풍부한 애니메이션 라이브러리. 38KB.
참치를 움직이기 위해서만 사용하는 라이브러리가 아닙니다.
duration의 지정이 ms 는 아니고 s 이므로 주의가 필요합니다.

Velocity.js


const velocityPromise = () => {
  return new Promise(resolve => {
    const el = document.getElementById('velocity')

    Velocity(el, {translateX: windowWidth}, {duration: 0})
    Velocity(el, {translateX: -elementWidth}, {
      duration,
      easing: 'easeInOutCubic',
      complete: () => resolve()
    })
  })
}

jQuery처럼 쓸 수 있는 애니메이션 라이브러리. 16KB.

anime.js


const animePromise = () => {
  return new Promise(resolve => {
    const el = document.getElementById('anime')

    anime({
      targets: el,
      translateX: [windowWidth, -elementWidth],
      easing: 'easeInOutCubic',
      complete: () => resolve()
    })
  })
}

파일 사이즈도 기능도 심플한 애니메이션 라이브러리. 5KB.
다른 라이브러리보다 후발적인 것만으로 필요한 최소한의 기능을 작성하기 쉽게 만들어졌습니다.

비교





언제 어디서 누구와 보는지에 따라 받는 인상이 바뀌는 것이 참치의 재미.
만약 지금, anime.js가 기분 좋게 보이더라도, 다음 달에는 분명 느낌이 바뀌어 있을 것입니다.
솔직히, 큰 차이가 없습니다. (주관)

요약



브라우저상을 참치에 기분 좋게 수영해 주었으면 하는 생각이 오만하고,
애니메이션의 선정이라는 작업이 원래 불모였던 것 같아요.

참치에는 바다 속이 잘 어울린다.

출처



참고



이라 스토야
h tp // w w. 가자. 이 m/2016/04/b㎉g포 st_34. HTML

좋은 웹페이지 즐겨찾기