ベッセル曲線運動

2331 ワード

まず、ベッセル曲線のアルゴリズムは次のとおりです.
export const linear = (p1, p2, t) => {
  const [x1, y1] = p1
  const [x2, y2] = p2
  const x = x1 + (x2 - x1) * t
  const y = y1 + (y2 - y1) * t
  return {x, y}
}
export const quadratic = (p1, p2, cp, t) => {
  const [x1, y1] = p1
  const [x2, y2] = p2
  const [cx, cy] = cp
  let x = (1 - t) * (1 - t) * x1 + 2 * t * (1 - t) * cx + t * t * x2
  let y = (1 - t) * (1 - t) * y1 + 2 * t * (1 - t) * cy + t * t * y2
  return {x, y}
}
export const cubic = (p1, p2, cp1, cp2, t) => {
  const [x1, y1] = p1
  const [x2, y2] = p2
  const [cx1, cy1] = cp1
  const [cx2, cy2] = cp2
  let x =
    x1 * (1 - t) * (1 - t) * (1 - t) +
    3 * cx1 * t * (1 - t) * (1 - t) +
    3 * cx2 * t * t * (1 - t) +
    x2 * t * t * t
  let y =
    y1 * (1 - t) * (1 - t) * (1 - t) +
    3 * cy1 * t * (1 - t) * (1 - t) +
    3 * cy2 * t * t * (1 - t) +
    y2 * t * t * t
  return {x, y}
}

参考記事:https://segmentfault.com/a/11...その後、要素を移動させるにはrequestAnimationFrameを使うと便利です.この関数を実行するたびに、アルゴリズムによって現れる座標を計算し、動きの要素のleftとtopを与えるだけでよい.部分コード:
_move (target, count) {
    // count  requestAnimationFrame     ,t         t
    const t = this._calcT(count, t)
    //       
    const points = this._calcBezierPoint(t)
    target.style.left = points.x + 'px'
    target.style.top = points.y + 'px'
    //   t>=1,        
    if (t < 1) {
      count++
      requestAnimationFrame(() => {
        this._move(target, count)
      })
    } else {
      if (isDef(this.onEnd)) {
        this.onEnd()
      }
    }
  }

  play () {
    // target      
    // start     
    // end     
    const {target, start, end} = this
    if ([target, start, end].every(isDef)) {
      let count = 0
      target.style.position = 'absolute'
      requestAnimationFrame(() => {
        this._move(target, count)
      })
    } else {
      throw new Error('[error]: the target, start and end option must be defined.')
    }
    return this
  }

codepen npm