首先,贝塞尔曲线的算法如下:
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
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。