From e850c7a24a1c1601068171b1db3601a933186ee7 Mon Sep 17 00:00:00 2001 From: timhaywood Date: Tue, 14 Sep 2021 21:27:04 +1000 Subject: [PATCH] add remap keys --- package-lock.json | 14 ++++---- package.json | 2 +- src/index.ts | 91 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 95 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8298222..3714222 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "version": "2.0.3", "license": "MIT", "dependencies": { - "expression-globals-typescript": "^3.2.0" + "expression-globals-typescript": "^3.2.5" }, "devDependencies": { "@rollup/plugin-replace": "^2.3.3", @@ -106,9 +106,9 @@ "dev": true }, "node_modules/expression-globals-typescript": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/expression-globals-typescript/-/expression-globals-typescript-3.2.0.tgz", - "integrity": "sha512-JQFymCbvs9nE3W5KMfWP6IN/WcZ0KPS5ngKcI4FxFCArTbBwXcl+xWLdmb5YvsaUlG9fdasOSrutTeVsYGQ7gg==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/expression-globals-typescript/-/expression-globals-typescript-3.2.5.tgz", + "integrity": "sha512-ihtEfov+kGRMLaufssxjLnfiaLrM+WeEt9syNzHc7Z84HO2IkIxUj3Na8NBngFsGl3j2hCMJCyDtR4A1WVCtxg==", "dependencies": { "typedoc": "^0.20.34" } @@ -596,9 +596,9 @@ "dev": true }, "expression-globals-typescript": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/expression-globals-typescript/-/expression-globals-typescript-3.2.0.tgz", - "integrity": "sha512-JQFymCbvs9nE3W5KMfWP6IN/WcZ0KPS5ngKcI4FxFCArTbBwXcl+xWLdmb5YvsaUlG9fdasOSrutTeVsYGQ7gg==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/expression-globals-typescript/-/expression-globals-typescript-3.2.5.tgz", + "integrity": "sha512-ihtEfov+kGRMLaufssxjLnfiaLrM+WeEt9syNzHc7Z84HO2IkIxUj3Na8NBngFsGl3j2hCMJCyDtR4A1WVCtxg==", "requires": { "typedoc": "^0.20.34" } diff --git a/package.json b/package.json index 55b9f17..aae8a00 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,6 @@ "typescript": "^4.2.4" }, "dependencies": { - "expression-globals-typescript": "^3.2.0" + "expression-globals-typescript": "^3.2.5" } } diff --git a/src/index.ts b/src/index.ts index fa60a1f..bc2bf07 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,7 @@ import { PathValue, Value, SourceRect, + Property, } from 'expression-globals-typescript'; const thisProperty = new PathProperty([[0, 0]]); @@ -91,7 +92,7 @@ function getFunctions(time: number = thisLayer.time) { } /** - * + * For better bouncing, use our dedicated library eSpring: https://www.motiondeveloper.com/tools/espring * @param amp The amount of swing past each value * @param freq How fast the swing oscillates * @param decay Hoq quickly the swings reduce in value over time @@ -628,10 +629,10 @@ function getFunctions(time: number = thisLayer.time) { * @returns The given position value plus the offset, in the direction away from the given `anchor` */ function offsetFromAnchor( - position: Vector, - [offsetX, offsetY]: Vector, + position: Vector2D, + [offsetX, offsetY]: Vector2D, anchor: Anchor - ): Vector { + ): Vector2D { switch (anchor) { case 'topLeft': return thisLayer.add(position, [-offsetX, -offsetY]); @@ -646,6 +647,87 @@ function getFunctions(time: number = thisLayer.time) { } } + /** + * Remaps the animation on a given property to new values and times, but keeps the easing + * @param propertyWithAnimation The property that you've animated with the desired bezier curve + * @param timeStart The start time of the new animaiton + * @param valueStart The start value of the new animation + * @param timeEnd The end time of the new animation + * @param valueEnd The end value of the new animation + */ + function remapKeys( + propertyWithAnimation: Property, + timeStart: number, + valueStart: number | Vector, + timeEnd: number, + valueEnd: number | Vector + ) { + // The keys of the bezier curve to use + const keyOne = propertyWithAnimation.key(1); + const keyTwo = propertyWithAnimation.key(2); + + // Get the difference in animation durations between the two + // so we can match their durations + const originalDuration = keyTwo.time - keyOne.time; + const newDuration = timeEnd - timeStart; + const speedDelta = originalDuration / newDuration; + + // Move the existing animation to the new one in time + // And sample it at the desired speed + const movedTime = Math.max(time * speedDelta - timeStart, 0); + + // The value that animates with the desired easing + // at the desired speed, but original values + const keyedAnimation = propertyWithAnimation.valueAtTime( + keyOne.time + movedTime + ); + + const valueDelta = thisLayer.sub(valueEnd, valueStart); + + // Animate between array values + if ( + Array.isArray(keyedAnimation) && + Array.isArray(valueStart) && + Array.isArray(valueEnd) + ) { + const progress = keyedAnimation.map((dimension, index) => + thisLayer.linear( + dimension, + keyOne.value[index], + keyTwo.value[index], + 0, + 1 + ) + ) as Vector; + + return valueStart.map( + (dimension, index) => dimension + valueDelta[index] * progress[index] + ); + } + + // Animate between numbers + + if ( + typeof keyedAnimation === 'number' && + typeof keyOne.value === 'number' && + typeof keyTwo.value === 'number' && + typeof valueStart === 'number' && + typeof valueEnd === 'number' && + typeof valueDelta === 'number' + ) { + // Remap the keyed value to our new values + const progress = thisLayer.linear( + keyedAnimation, + keyOne.value, + keyTwo.value, + 0, + 1 + ) as number; + + return thisLayer.add(valueStart, thisLayer.mul(valueDelta, progress)); + } + } + return { attachKeys, bounceKeys, @@ -669,6 +751,7 @@ function getFunctions(time: number = thisLayer.time) { maintainScale, offsetFromAnchor, addLineBreaks, + remapKeys, }; }