UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering

360 lines (299 loc) 8.37 kB
/** * @file 缓动函数 * 提供常用的缓动函数。 */ export type Definition = (t: number) => number export type Names = | 'linear' | 'quad' | 'cubic' | 'inout' | 'exponential' | 'bounce' | 'easeInSine' | 'easeOutSine' | 'easeInOutSine' | 'easeInQuad' | 'easeOutQuad' | 'easeInOutQuad' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic' | 'easeInQuart' | 'easeOutQuart' | 'easeInOutQuart' | 'easeInQuint' | 'easeOutQuint' | 'easeInOutQuint' | 'easeInExpo' | 'easeOutExpo' | 'easeInOutExpo' | 'easeInCirc' | 'easeOutCirc' | 'easeInOutCirc' | 'easeInBack' | 'easeOutBack' | 'easeInOutBack' | 'easeInElastic' | 'easeOutElastic' | 'easeInOutElastic' | 'easeInBounce' | 'easeOutBounce' | 'easeInOutBounce' export const linear: Definition = (t) => t export const quad: Definition = (t) => t * t export const cubic: Definition = (t) => t * t * t export const inout: Definition = (t) => { if (t <= 0) { return 0 } if (t >= 1) { return 1 } const t2 = t * t const t3 = t2 * t return 4 * (t < 0.5 ? t3 : 3 * (t - t2) + t3 - 0.75) } export const exponential: Definition = (t) => { return 2 ** (10 * (t - 1)) // eslint-disable-line } export const bounce = ((t: number) => { for (let a = 0, b = 1; ; a += b, b /= 2) { if (t >= (7 - 4 * a) / 11) { const q = (11 - 6 * a - 11 * t) / 4 return -q * q + b * b } } }) as Definition export const decorators = { reverse(f: Definition): Definition { return (t) => 1 - f(1 - t) }, reflect(f: Definition): Definition { return (t) => 0.5 * (t < 0.5 ? f(2 * t) : 2 - f(2 - 2 * t)) }, clamp(f: Definition, n = 0, x = 1): Definition { return (t) => { const r = f(t) return r < n ? n : r > x ? x : r } }, back(s = 1.70158): Definition { return (t) => t * t * ((s + 1) * t - s) }, elastic(x = 1.5): Definition { return (t) => 2 ** (10 * (t - 1)) * Math.cos(((20 * Math.PI * x) / 3) * t) }, } // Slight acceleration from zero to full speed export function easeInSine(t: number) { return -1 * Math.cos(t * (Math.PI / 2)) + 1 } // Slight deceleration at the end export function easeOutSine(t: number) { return Math.sin(t * (Math.PI / 2)) } // Slight acceleration at beginning and slight deceleration at end export function easeInOutSine(t: number) { return -0.5 * (Math.cos(Math.PI * t) - 1) } // Accelerating from zero velocity export function easeInQuad(t: number) { return t * t } // Decelerating to zero velocity export function easeOutQuad(t: number) { return t * (2 - t) } // Acceleration until halfway, then deceleration export function easeInOutQuad(t: number) { return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t } // Accelerating from zero velocity export function easeInCubic(t: number) { return t * t * t } // Decelerating to zero velocity export function easeOutCubic(t: number) { const t1 = t - 1 return t1 * t1 * t1 + 1 } // Acceleration until halfway, then deceleration export function easeInOutCubic(t: number) { return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1 } // Accelerating from zero velocity export function easeInQuart(t: number) { return t * t * t * t } // Decelerating to zero velocity export function easeOutQuart(t: number) { const t1 = t - 1 return 1 - t1 * t1 * t1 * t1 } // Acceleration until halfway, then deceleration export function easeInOutQuart(t: number) { const t1 = t - 1 return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * t1 * t1 * t1 * t1 } // Accelerating from zero velocity export function easeInQuint(t: number) { return t * t * t * t * t } // Decelerating to zero velocity export function easeOutQuint(t: number) { const t1 = t - 1 return 1 + t1 * t1 * t1 * t1 * t1 } // Acceleration until halfway, then deceleration export function easeInOutQuint(t: number) { const t1 = t - 1 return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * t1 * t1 * t1 * t1 * t1 } // Accelerate exponentially until finish export function easeInExpo(t: number) { if (t === 0) { return 0 } return 2 ** (10 * (t - 1)) } // Initial exponential acceleration slowing to stop export function easeOutExpo(t: number) { if (t === 1) { return 1 } return -(2 ** (-10 * t)) + 1 } // Exponential acceleration and deceleration export function easeInOutExpo(t: number) { if (t === 0 || t === 1) { return t } const scaledTime = t * 2 const scaledTime1 = scaledTime - 1 if (scaledTime < 1) { return 0.5 * 2 ** (10 * scaledTime1) } return 0.5 * (-(2 ** (-10 * scaledTime1)) + 2) } // Increasing velocity until stop export function easeInCirc(t: number) { const scaledTime = t / 1 return -1 * (Math.sqrt(1 - scaledTime * t) - 1) } // Start fast, decreasing velocity until stop export function easeOutCirc(t: number) { const t1 = t - 1 return Math.sqrt(1 - t1 * t1) } // Fast increase in velocity, fast decrease in velocity export function easeInOutCirc(t: number) { const scaledTime = t * 2 const scaledTime1 = scaledTime - 2 if (scaledTime < 1) { return -0.5 * (Math.sqrt(1 - scaledTime * scaledTime) - 1) } return 0.5 * (Math.sqrt(1 - scaledTime1 * scaledTime1) + 1) } // Slow movement backwards then fast snap to finish export function easeInBack(t: number, magnitude = 1.70158) { return t * t * ((magnitude + 1) * t - magnitude) } // Fast snap to backwards point then slow resolve to finish export function easeOutBack(t: number, magnitude = 1.70158) { const scaledTime = t / 1 - 1 return ( scaledTime * scaledTime * ((magnitude + 1) * scaledTime + magnitude) + 1 ) } // Slow movement backwards, fast snap to past finish, slow resolve to finish export function easeInOutBack(t: number, magnitude = 1.70158) { const scaledTime = t * 2 const scaledTime2 = scaledTime - 2 const s = magnitude * 1.525 if (scaledTime < 1) { return 0.5 * scaledTime * scaledTime * ((s + 1) * scaledTime - s) } return 0.5 * (scaledTime2 * scaledTime2 * ((s + 1) * scaledTime2 + s) + 2) } // Bounces slowly then quickly to finish export function easeInElastic(t: number, magnitude = 0.7) { if (t === 0 || t === 1) { return t } const scaledTime = t / 1 const scaledTime1 = scaledTime - 1 const p = 1 - magnitude const s = (p / (2 * Math.PI)) * Math.asin(1) return -( 2 ** (10 * scaledTime1) * // eslint-disable-line Math.sin(((scaledTime1 - s) * (2 * Math.PI)) / p) ) } // Fast acceleration, bounces to zero export function easeOutElastic(t: number, magnitude = 0.7) { const p = 1 - magnitude const scaledTime = t * 2 if (t === 0 || t === 1) { return t } const s = (p / (2 * Math.PI)) * Math.asin(1) return ( 2 ** (-10 * scaledTime) * // eslint-disable-line Math.sin(((scaledTime - s) * (2 * Math.PI)) / p) + 1 ) } // Slow start and end, two bounces sandwich a fast motion export function easeInOutElastic(t: number, magnitude = 0.65) { const p = 1 - magnitude if (t === 0 || t === 1) { return t } const scaledTime = t * 2 const scaledTime1 = scaledTime - 1 const s = (p / (2 * Math.PI)) * Math.asin(1) if (scaledTime < 1) { return ( -0.5 * (2 ** (10 * scaledTime1) * // eslint-disable-line Math.sin(((scaledTime1 - s) * (2 * Math.PI)) / p)) ) } return ( 2 ** (-10 * scaledTime1) * // eslint-disable-line Math.sin(((scaledTime1 - s) * (2 * Math.PI)) / p) * 0.5 + 1 ) } // Bounce to completion export function easeOutBounce(t: number) { const scaledTime = t / 1 if (scaledTime < 1 / 2.75) { return 7.5625 * scaledTime * scaledTime } if (scaledTime < 2 / 2.75) { const scaledTime2 = scaledTime - 1.5 / 2.75 return 7.5625 * scaledTime2 * scaledTime2 + 0.75 } if (scaledTime < 2.5 / 2.75) { const scaledTime2 = scaledTime - 2.25 / 2.75 return 7.5625 * scaledTime2 * scaledTime2 + 0.9375 } { const scaledTime2 = scaledTime - 2.625 / 2.75 return 7.5625 * scaledTime2 * scaledTime2 + 0.984375 } } // Bounce increasing in velocity until completion export function easeInBounce(t: number) { return 1 - easeOutBounce(1 - t) } // Bounce in and bounce out export function easeInOutBounce(t: number) { if (t < 0.5) { return easeInBounce(t * 2) * 0.5 } return easeOutBounce(t * 2 - 1) * 0.5 + 0.5 }