Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to write an anime library #22

Open
wangbinyq opened this issue Apr 17, 2018 · 0 comments
Open

How to write an anime library #22

wangbinyq opened this issue Apr 17, 2018 · 0 comments

Comments

@wangbinyq
Copy link
Owner

wangbinyq commented Apr 17, 2018

The engine

We need a mechanism to deal with layout thrashing. So we have an engine that group all animations into to a requestAnimationFrame callback.

const engine = (function () {
  let animations = {}
  let raf = 0
  
  function play () { raf = requestAnimationFrame(step) }
  function step () { animations.forEach((anim) => anim.step()); if (animations.length) play() }
  function add (anim) { animations.push(anim) }
  function remove (anim) { const index = animations.indexOf(index); animations.splice(index, 1) }

  return {
    play, step, add, remove, raf
  } 
})()

The tween and animation

A tween object repersent a property change. It is an object like this:

const defaultTweenSetting = {
  target: Element,
  property: string,
  duration: number,
  easing: Function,
  from: number,
  to: number,
  unit: string
}

This object can describe what to be change (target, property), how long it will last (duration), how does the chnage looks like (easing), and the start and end value (from, to and unit).

An animation object group list of tweens and play the real animation by add it self to the engine and step the tween.

class Animation {
  constructor (tweens) {
    this.tweens
  }

  step (now) {
    let elapsed = 0
    if (!this.startTime) {
       this.startTime = now
    }
    const elapsed = now - this.startTime
    finisheds = this.tweens.map((tween) => {
      const process = Math.min(1, elapsed / tween.duration)
      const eased = tween.easing(process)
      const value = tween.from + (tween.to - tween.from) * eased
      tween.target.style[tween.property] = value + tween.unit
      if (process >= 1) {
        return true
      }
    })
    if (finisheds.every((f) => f)) {
       this.pause()
    }
  }

  play () {
    engine.add(this)
  }
  pause () {
    engine.remove(this)
  }
  restart () {
    this.pause()
    this.startTime = 0
    this.play()
  }
}

The Libraries

Now we have engine, tween and Animtaion. Use those object or class you can build some style animatons you what to. But it's not enough, we need construct the tweens ourself and we only support css style property animation.
There are some realy awesome animation libraries exist:

  • anime.js: This is what inspire our little animation engine with more features like transform, svg and object property (we can do it by add a type field to our tween and add the corresponding changes code to Animation.step function), timeline, can automaticlly transform params to tweens etc.
  • velocityjs: It's incredibly fast, and it features color animation, transforms, loops, easings, SVG support, and scrolling.

Others

Unit transfrom

  1. jquery.adjustCSS: calculate the scale between current unit and the excepted unit, then apply the new united value.
  2. velocityjs:
if (fromUnit !== toUnit) {
  currentValue = `calc(${from * (1 - eased) + fromUnit} + ${to * eased + toUnit})`
}
@wangbinyq wangbinyq assigned wangbinyq and unassigned wangbinyq Apr 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant