From b95ba3d5c3c6a7a93a2a2a1b02f550b9c33a288e Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Wed, 31 Aug 2022 09:53:54 -0400 Subject: [PATCH] Convert the easing helpers to typescript (#10627) Co-authored-by: Chart.js <> --- src/helpers/helpers.easing.js | 122 ----------------------------- src/helpers/helpers.easing.ts | 124 ++++++++++++++++++++++++++++++ src/helpers/types.ts | 1 + types/helpers/helpers.easing.d.ts | 5 -- types/index.d.ts | 35 +-------- 5 files changed, 127 insertions(+), 160 deletions(-) delete mode 100644 src/helpers/helpers.easing.js create mode 100644 src/helpers/helpers.easing.ts delete mode 100644 types/helpers/helpers.easing.d.ts diff --git a/src/helpers/helpers.easing.js b/src/helpers/helpers.easing.js deleted file mode 100644 index 849ffdfa1..000000000 --- a/src/helpers/helpers.easing.js +++ /dev/null @@ -1,122 +0,0 @@ -import {PI, TAU, HALF_PI} from './helpers.math'; - -const atEdge = (t) => t === 0 || t === 1; -const elasticIn = (t, s, p) => -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * TAU / p)); -const elasticOut = (t, s, p) => Math.pow(2, -10 * t) * Math.sin((t - s) * TAU / p) + 1; - -/** - * Easing functions adapted from Robert Penner's easing equations. - * @namespace Chart.helpers.easing.effects - * @see http://www.robertpenner.com/easing/ - */ -const effects = { - linear: t => t, - - easeInQuad: t => t * t, - - easeOutQuad: t => -t * (t - 2), - - easeInOutQuad: t => ((t /= 0.5) < 1) - ? 0.5 * t * t - : -0.5 * ((--t) * (t - 2) - 1), - - easeInCubic: t => t * t * t, - - easeOutCubic: t => (t -= 1) * t * t + 1, - - easeInOutCubic: t => ((t /= 0.5) < 1) - ? 0.5 * t * t * t - : 0.5 * ((t -= 2) * t * t + 2), - - easeInQuart: t => t * t * t * t, - - easeOutQuart: t => -((t -= 1) * t * t * t - 1), - - easeInOutQuart: t => ((t /= 0.5) < 1) - ? 0.5 * t * t * t * t - : -0.5 * ((t -= 2) * t * t * t - 2), - - easeInQuint: t => t * t * t * t * t, - - easeOutQuint: t => (t -= 1) * t * t * t * t + 1, - - easeInOutQuint: t => ((t /= 0.5) < 1) - ? 0.5 * t * t * t * t * t - : 0.5 * ((t -= 2) * t * t * t * t + 2), - - easeInSine: t => -Math.cos(t * HALF_PI) + 1, - - easeOutSine: t => Math.sin(t * HALF_PI), - - easeInOutSine: t => -0.5 * (Math.cos(PI * t) - 1), - - easeInExpo: t => (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)), - - easeOutExpo: t => (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1, - - easeInOutExpo: t => atEdge(t) ? t : t < 0.5 - ? 0.5 * Math.pow(2, 10 * (t * 2 - 1)) - : 0.5 * (-Math.pow(2, -10 * (t * 2 - 1)) + 2), - - easeInCirc: t => (t >= 1) ? t : -(Math.sqrt(1 - t * t) - 1), - - easeOutCirc: t => Math.sqrt(1 - (t -= 1) * t), - - easeInOutCirc: t => ((t /= 0.5) < 1) - ? -0.5 * (Math.sqrt(1 - t * t) - 1) - : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1), - - easeInElastic: t => atEdge(t) ? t : elasticIn(t, 0.075, 0.3), - - easeOutElastic: t => atEdge(t) ? t : elasticOut(t, 0.075, 0.3), - - easeInOutElastic(t) { - const s = 0.1125; - const p = 0.45; - return atEdge(t) ? t : - t < 0.5 - ? 0.5 * elasticIn(t * 2, s, p) - : 0.5 + 0.5 * elasticOut(t * 2 - 1, s, p); - }, - - easeInBack(t) { - const s = 1.70158; - return t * t * ((s + 1) * t - s); - }, - - easeOutBack(t) { - const s = 1.70158; - return (t -= 1) * t * ((s + 1) * t + s) + 1; - }, - - easeInOutBack(t) { - let s = 1.70158; - if ((t /= 0.5) < 1) { - return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); - } - return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); - }, - - easeInBounce: t => 1 - effects.easeOutBounce(1 - t), - - easeOutBounce(t) { - const m = 7.5625; - const d = 2.75; - if (t < (1 / d)) { - return m * t * t; - } - if (t < (2 / d)) { - return m * (t -= (1.5 / d)) * t + 0.75; - } - if (t < (2.5 / d)) { - return m * (t -= (2.25 / d)) * t + 0.9375; - } - return m * (t -= (2.625 / d)) * t + 0.984375; - }, - - easeInOutBounce: t => (t < 0.5) - ? effects.easeInBounce(t * 2) * 0.5 - : effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5, -}; - -export default effects; diff --git a/src/helpers/helpers.easing.ts b/src/helpers/helpers.easing.ts new file mode 100644 index 000000000..f98917a5b --- /dev/null +++ b/src/helpers/helpers.easing.ts @@ -0,0 +1,124 @@ +import {PI, TAU, HALF_PI} from './helpers.math'; + +const atEdge = (t: number) => t === 0 || t === 1; +const elasticIn = (t: number, s: number, p: number) => -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * TAU / p)); +const elasticOut = (t: number, s: number, p: number) => Math.pow(2, -10 * t) * Math.sin((t - s) * TAU / p) + 1; + +/** + * Easing functions adapted from Robert Penner's easing equations. + * @namespace Chart.helpers.easing.effects + * @see http://www.robertpenner.com/easing/ + */ +const effects = { + linear: (t: number) => t, + + easeInQuad: (t: number) => t * t, + + easeOutQuad: (t: number) => -t * (t - 2), + + easeInOutQuad: (t: number) => ((t /= 0.5) < 1) + ? 0.5 * t * t + : -0.5 * ((--t) * (t - 2) - 1), + + easeInCubic: (t: number) => t * t * t, + + easeOutCubic: (t: number) => (t -= 1) * t * t + 1, + + easeInOutCubic: (t: number) => ((t /= 0.5) < 1) + ? 0.5 * t * t * t + : 0.5 * ((t -= 2) * t * t + 2), + + easeInQuart: (t: number) => t * t * t * t, + + easeOutQuart: (t: number) => -((t -= 1) * t * t * t - 1), + + easeInOutQuart: (t: number) => ((t /= 0.5) < 1) + ? 0.5 * t * t * t * t + : -0.5 * ((t -= 2) * t * t * t - 2), + + easeInQuint: (t: number) => t * t * t * t * t, + + easeOutQuint: (t: number) => (t -= 1) * t * t * t * t + 1, + + easeInOutQuint: (t: number) => ((t /= 0.5) < 1) + ? 0.5 * t * t * t * t * t + : 0.5 * ((t -= 2) * t * t * t * t + 2), + + easeInSine: (t: number) => -Math.cos(t * HALF_PI) + 1, + + easeOutSine: (t: number) => Math.sin(t * HALF_PI), + + easeInOutSine: (t: number) => -0.5 * (Math.cos(PI * t) - 1), + + easeInExpo: (t: number) => (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)), + + easeOutExpo: (t: number) => (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1, + + easeInOutExpo: (t: number) => atEdge(t) ? t : t < 0.5 + ? 0.5 * Math.pow(2, 10 * (t * 2 - 1)) + : 0.5 * (-Math.pow(2, -10 * (t * 2 - 1)) + 2), + + easeInCirc: (t: number) => (t >= 1) ? t : -(Math.sqrt(1 - t * t) - 1), + + easeOutCirc: (t: number) => Math.sqrt(1 - (t -= 1) * t), + + easeInOutCirc: (t: number) => ((t /= 0.5) < 1) + ? -0.5 * (Math.sqrt(1 - t * t) - 1) + : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1), + + easeInElastic: (t: number) => atEdge(t) ? t : elasticIn(t, 0.075, 0.3), + + easeOutElastic: (t: number) => atEdge(t) ? t : elasticOut(t, 0.075, 0.3), + + easeInOutElastic(t: number) { + const s = 0.1125; + const p = 0.45; + return atEdge(t) ? t : + t < 0.5 + ? 0.5 * elasticIn(t * 2, s, p) + : 0.5 + 0.5 * elasticOut(t * 2 - 1, s, p); + }, + + easeInBack(t: number) { + const s = 1.70158; + return t * t * ((s + 1) * t - s); + }, + + easeOutBack(t: number) { + const s = 1.70158; + return (t -= 1) * t * ((s + 1) * t + s) + 1; + }, + + easeInOutBack(t: number) { + let s = 1.70158; + if ((t /= 0.5) < 1) { + return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); + } + return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); + }, + + easeInBounce: (t: number) => 1 - effects.easeOutBounce(1 - t), + + easeOutBounce(t: number) { + const m = 7.5625; + const d = 2.75; + if (t < (1 / d)) { + return m * t * t; + } + if (t < (2 / d)) { + return m * (t -= (1.5 / d)) * t + 0.75; + } + if (t < (2.5 / d)) { + return m * (t -= (2.25 / d)) * t + 0.9375; + } + return m * (t -= (2.625 / d)) * t + 0.984375; + }, + + easeInOutBounce: (t: number) => (t < 0.5) + ? effects.easeInBounce(t * 2) * 0.5 + : effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5, +} as const; + +export type EasingFunction = keyof typeof effects + +export default effects; diff --git a/src/helpers/types.ts b/src/helpers/types.ts index 55b6e31d9..d69c088d6 100644 --- a/src/helpers/types.ts +++ b/src/helpers/types.ts @@ -5,4 +5,5 @@ // export * from '.'; export * from './helpers.core'; +export * from './helpers.easing'; export * from '../../types/helpers'; diff --git a/types/helpers/helpers.easing.d.ts b/types/helpers/helpers.easing.d.ts deleted file mode 100644 index 7fb2a3877..000000000 --- a/types/helpers/helpers.easing.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { EasingFunction } from '..'; - -export type EasingFunctionSignature = (t: number) => number; - -export declare const easingEffects: Record; diff --git a/types/index.d.ts b/types/index.d.ts index bb93f117c..06803e8b1 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,6 +1,7 @@ import { DeepPartial, DistributiveArray, UnionToIntersection } from './utils'; import { TimeUnit } from '../src/core/core.adapters'; +import { EasingFunction } from '../src/helpers/helpers.easing'; import { AnimationEvent } from './animation'; import { AnyObject, EmptyObject } from './basic'; import { Color } from './color'; @@ -8,6 +9,7 @@ import Element from '../src/core/core.element'; import { ChartArea, Padding, Point } from './geometric'; import { LayoutItem, LayoutPosition } from './layout'; +export { EasingFunction } from '../src/helpers/helpers.easing'; export { Animation, Animations, Animator, AnimationEvent } from './animation'; export { Color } from './color'; export { ChartArea, Point } from './geometric'; @@ -1528,39 +1530,6 @@ export interface CoreChartOptions extends ParsingOption }>; } -export type EasingFunction = - | 'linear' - | 'easeInQuad' - | 'easeOutQuad' - | 'easeInOutQuad' - | 'easeInCubic' - | 'easeOutCubic' - | 'easeInOutCubic' - | 'easeInQuart' - | 'easeOutQuart' - | 'easeInOutQuart' - | 'easeInQuint' - | 'easeOutQuint' - | 'easeInOutQuint' - | 'easeInSine' - | 'easeOutSine' - | 'easeInOutSine' - | 'easeInExpo' - | 'easeOutExpo' - | 'easeInOutExpo' - | 'easeInCirc' - | 'easeOutCirc' - | 'easeInOutCirc' - | 'easeInElastic' - | 'easeOutElastic' - | 'easeInOutElastic' - | 'easeInBack' - | 'easeOutBack' - | 'easeInOutBack' - | 'easeInBounce' - | 'easeOutBounce' - | 'easeInOutBounce'; - export type AnimationSpec = { /** * The number of milliseconds an animation takes. -- 2.47.3