UNPKG

wangbd-myui

Version:

MY前端基础框架核心组件库

337 lines (301 loc) 6.66 kB
/** * 缓动动画函数和各类算法 * @module $ui/utils/tween * @author 陈华春 */ // 动画每秒60帧 const UPDATE_TIME = 1000 / 60 const pow = Math.pow const sqrt = Math.sqrt const sin = Math.sin const cos = Math.cos const PI = Math.PI const c1 = 1.70158 const c2 = c1 * 1.525 const c3 = c1 + 1 const c4 = (2 * PI) / 3 const c5 = (2 * PI) / 4.5 // 动画执行函数 const rAF = window.requestAnimationFrame || function (cb) { setTimeout(cb, UPDATE_TIME) } /** * 缓动动画函数 * @param {number} startValue 开始时的值 * @param {number} endValue 结束时的值 * @param {number} during 动画持续时间,单位:毫秒 * @param {Function} easingFunc 缓动算法函数 * @param {function} stepCb 每次改变的回调函数 * @returns {Promise} Promise实例 * * @example * * import tween, {easeInCubic} from '@/utils/tween' * tween(0, 100, 300, easeInCubic, function(val){ * console.log(val) * // to do something * }) */ export default function (startValue, endValue, during, easingFunc, stepCb) { // 改变的值大小 const changeValue = endValue - startValue // 指定时间内更新的次数 const updateCount = during / UPDATE_TIME // 每次更新的值距离 const perUpdateDistance = 1 / updateCount let position = 0 return new Promise(resolve => { function step() { const state = startValue + changeValue * easingFunc(position) let result = stepCb(state) // 如果返回false,停止运行 if (result === false) return position += perUpdateDistance if (position < 1) { rAF(step) } else { rAF(() => { result = stepCb(endValue) if (result === false) return resolve() }) } } step() }) } /** * easeInQuad * @param {number} x * @returns {number} */ export function easeInQuad(x) { return x * x } /** * easeOutQuad * @param {number} x * @returns {number} */ export function easeOutQuad(x) { return 1 - (1 - x) * (1 - x) } /** * easeInOutQuad * @param x * @returns {number} */ export function easeInOutQuad(x) { return x < 0.5 ? 2 * x * x : 1 - pow(-2 * x + 2, 2) / 2 } /** * easeInCubic * @param x * @returns {number} */ export function easeInCubic(x) { return x * x * x } /** * easeOutCubic * @param x * @returns {number} */ export function easeOutCubic(x) { return 1 - pow(1 - x, 3) } /** * easeInOutCubic * @param x * @returns {number} */ export function easeInOutCubic(x) { return x < 0.5 ? 4 * x * x * x : 1 - pow(-2 * x + 2, 3) / 2; } /** * easeInQuart * @param x * @returns {number} */ export function easeInQuart(x) { return x * x * x * x; } /** * easeInQuart * @param x * @returns {number} */ export function easeOutQuart(x) { return 1 - pow(1 - x, 4) } /** * easeInOutQuart * @param x * @returns {number} */ export function easeInOutQuart(x) { return x < 0.5 ? 8 * x * x * x * x : 1 - pow(-2 * x + 2, 4) / 2; } /** * easeInQuint * @param x * @returns {number} */ export function easeInQuint(x) { return x * x * x * x * x } /** * easeOutQuint * @param x * @returns {number} */ export function easeOutQuint(x) { return 1 - pow(1 - x, 5) } /** * easeInOutQuint * @param x * @returns {number} */ export function easeInOutQuint(x) { return x < 0.5 ? 16 * x * x * x * x * x : 1 - pow(-2 * x + 2, 5) / 2; } /** * easeInSine * @param x * @returns {number} */ export function easeInSine(x) { return 1 - cos(x * PI / 2) } /** * easeOutSine * @param x * @returns {number} */ export function easeOutSine(x) { return sin(x * PI / 2) } /** * easeInOutSine * @param x * @returns {number} */ export function easeInOutSine(x) { return -(cos(PI * x) - 1) / 2 } /** * easeInExpo * @param x * @returns {number} */ export function easeInExpo(x) { return x === 0 ? 0 : pow(2, 10 * x - 10) } /** * easeOutExpo * @param x * @returns {number} */ export function easeOutExpo(x) { return x === 1 ? 1 : 1 - pow(2, -10 * x) } export function easeInOutExpo(x) { return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? pow(2, 20 * x - 10) / 2 : (2 - pow(2, -20 * x + 10)) / 2 } /** * easeInCirc * @param x * @returns {number} */ export function easeInCirc(x) { return 1 - sqrt(1 - pow(x, 2)) } /** * easeOutCirc * @param x * @returns {number} */ export function easeOutCirc(x) { return sqrt(1 - pow(x - 1, 2)) } export function easeInOutCirc(x) { return x < 0.5 ? (1 - sqrt(1 - pow(2 * x, 2))) / 2 : (sqrt(1 - pow(-2 * x + 2, 2)) + 1) / 2 } /** * easeInElastic * @param x * @returns {number} */ export function easeInElastic(x) { return x === 0 ? 0 : x === 1 ? 1 : -pow(2, 10 * x - 10) * sin((x * 10 - 10.75) * c4) } /** * easeOutElastic * @param x * @returns {number} */ export function easeOutElastic(x) { return x === 0 ? 0 : x === 1 ? 1 : pow(2, -10 * x) * sin((x * 10 - 0.75) * c4) + 1 } export function easeInOutElastic(x) { return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? -(pow(2, 20 * x - 10) * sin((20 * x - 11.125) * c5)) / 2 : pow(2, -20 * x + 10) * sin((20 * x - 11.125) * c5) / 2 + 1 } /** * easeInBack * @param x * @returns {number} */ export function easeInBack(x) { return c3 * x * x * x - c1 * x * x } /** * easeOutBack * @param x * @returns {number} */ export function easeOutBack(x) { return 1 + c3 * pow(x - 1, 3) + c1 * pow(x - 1, 2) } /** * easeInOutBack * @param x * @returns {number} */ export function easeInOutBack(x) { return x < 0.5 ? (pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2 : (pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2 } /** * easeInBounce * @param x * @returns {number} */ export function easeInBounce(x) { return 1 - easeOutBounce(1 - x) } /** * easeOutBounce * @param x * @returns {number} */ export function easeOutBounce(x) { const n1 = 7.5625 const d1 = 2.75 if (x < 1 / d1) { return n1 * x * x } else if (x < 2 / d1) { return n1 * (x -= (1.5 / d1)) * x + 0.75; } else if (x < 2.5 / d1) { return n1 * (x -= (2.25 / d1)) * x + 0.9375; } else { return n1 * (x -= (2.625 / d1)) * x + 0.984375; } } /** * easeInOutBounce * @param x * @returns {number} */ export function easeInOutBounce(x) { return x < 0.5 ? (1 - easeOutBounce(1 - 2 * x)) / 2 : (1 + easeOutBounce(2 * x - 1)) / 2 }