补间动画库
补间动画介绍
补间动画指的是做FLASH、VIDEO动画时,在两个关键帧中间需要做“补间动画”,才能实现图画的运动;插入补间动画后两个关键帧之间的插补帧是由计算机自动运算而得到的。
背景
做一个播放视频同时要播放动画的需求
适用场景
- 关键帧动画
- 视频转场动画
- 音频淡入淡出
问题
计算开始点与结束点之间的动画位置
思路
0______________________9____10
(90%)
// 设常量确定两点start、end:
const start = 0
const end = 10
// 设变量current
let current = 9
线性动画时,设start=0,end=10,x1=0,x2=100(x的值从0偏移到100),当current=9时,x=90
得出公式:x = x2 * current / (end - start) + x1
此例子:x = 100 * 9 / 10 + 0
线性动画函数
/**
* 线性动画函数
* @param {number} t 当前时间
* @param {number} b 初始值
* @param {number} c 变化值
* @param {number} d 动画时长
*/
const linear = (t, b, c, d) => {
return c * t / d + b
}
var start = 0
var end = 10
var current = 9
var time = current - start
var duration = end - start
linear(time, 0, 100 - 0, duration)
// => 90
var x1 = 50
var x2 = 100
var change = x2 - x1
var start = 10
var end = 20
var current = 10
var time = current - start
var duration = end - start
linear(time, x1, change, duration)
// => 50
封装动画库
支持批量处理
/**
* 动画函数
* @param {object} options
*/
const animation = (options) => {
options = options || {}
let result = {}
let current = options.current
let start = options.start
let end = options.end
let easeFn = options.easeFn
let form = options.form
let to = options.to
if (start > end) {
throw Error(`Start cannot be greater than the end`)
}
if (start < 0 || end < 0) {
throw Error(`Start or end value cannot be less than 0`)
}
let time = (current - start)
let duration = (end - start)
easeFn = easeFn || linear
// 处理undefined
if (isUndefined(form) || isUndefined(to)) {
let num = easeFn(time, 0, 1, duration)
if (num > 1) {
num = 1
}
return num
}
// 处理不是对象
if (!isPlainObject(form) || !isPlainObject(to)) {
throw Error('form and to is not object')
}
// 处理对象
for (const key in to) {
if (to.hasOwnProperty(key)) {
const formValue = Number(form[key])
const toValue = Number(to[key])
if (isNaN(formValue) || isNaN(toValue)) {
throw Error('value is not number')
}
const change = toValue - formValue
result[key] = easeFn(time, formValue, change, duration)
}
}
return result
}
使用
npm install transition-animation -S
import ANIMATION from 'transition-animation'
const current = 9
const start = 0
const end = 10
const result = ANIMATION.animation({
current,
start,
end,
form: {
x: 0,
y: 0
},
to: {
x: 100,
y: 200
}
});
// result -> { x: 90, y: 180}