Skip to content

Commit df156e0

Browse files
authored
Merge pull request #5 from motiondeveloper/feat/add-remap-keys
add remap keys
2 parents ecab84e + e850c7a commit df156e0

File tree

3 files changed

+95
-12
lines changed

3 files changed

+95
-12
lines changed

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@
3333
"typescript": "^4.2.4"
3434
},
3535
"dependencies": {
36-
"expression-globals-typescript": "^3.2.0"
36+
"expression-globals-typescript": "^3.2.5"
3737
}
3838
}

src/index.ts

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
PathValue,
99
Value,
1010
SourceRect,
11+
Property,
1112
} from 'expression-globals-typescript';
1213

1314
const thisProperty = new PathProperty([[0, 0]]);
@@ -91,7 +92,7 @@ function getFunctions(time: number = thisLayer.time) {
9192
}
9293

9394
/**
94-
*
95+
* For better bouncing, use our dedicated library eSpring: https://www.motiondeveloper.com/tools/espring
9596
* @param amp The amount of swing past each value
9697
* @param freq How fast the swing oscillates
9798
* @param decay Hoq quickly the swings reduce in value over time
@@ -628,10 +629,10 @@ function getFunctions(time: number = thisLayer.time) {
628629
* @returns The given position value plus the offset, in the direction away from the given `anchor`
629630
*/
630631
function offsetFromAnchor(
631-
position: Vector,
632-
[offsetX, offsetY]: Vector,
632+
position: Vector2D,
633+
[offsetX, offsetY]: Vector2D,
633634
anchor: Anchor
634-
): Vector {
635+
): Vector2D {
635636
switch (anchor) {
636637
case 'topLeft':
637638
return thisLayer.add(position, [-offsetX, -offsetY]);
@@ -646,6 +647,87 @@ function getFunctions(time: number = thisLayer.time) {
646647
}
647648
}
648649

650+
/**
651+
* Remaps the animation on a given property to new values and times, but keeps the easing
652+
* @param propertyWithAnimation The property that you've animated with the desired bezier curve
653+
* @param timeStart The start time of the new animaiton
654+
* @param valueStart The start value of the new animation
655+
* @param timeEnd The end time of the new animation
656+
* @param valueEnd The end value of the new animation
657+
*/
658+
function remapKeys(
659+
propertyWithAnimation: Property<number | Vector>,
660+
timeStart: number,
661+
valueStart: number | Vector,
662+
timeEnd: number,
663+
valueEnd: number | Vector
664+
) {
665+
// The keys of the bezier curve to use
666+
const keyOne = propertyWithAnimation.key(1);
667+
const keyTwo = propertyWithAnimation.key(2);
668+
669+
// Get the difference in animation durations between the two
670+
// so we can match their durations
671+
const originalDuration = keyTwo.time - keyOne.time;
672+
const newDuration = timeEnd - timeStart;
673+
const speedDelta = originalDuration / newDuration;
674+
675+
// Move the existing animation to the new one in time
676+
// And sample it at the desired speed
677+
const movedTime = Math.max(time * speedDelta - timeStart, 0);
678+
679+
// The value that animates with the desired easing
680+
// at the desired speed, but original values
681+
const keyedAnimation = propertyWithAnimation.valueAtTime(
682+
keyOne.time + movedTime
683+
);
684+
685+
const valueDelta = thisLayer.sub(valueEnd, valueStart);
686+
687+
// Animate between array values
688+
if (
689+
Array.isArray(keyedAnimation) &&
690+
Array.isArray(valueStart) &&
691+
Array.isArray(valueEnd)
692+
) {
693+
const progress = keyedAnimation.map((dimension, index) =>
694+
thisLayer.linear(
695+
dimension,
696+
keyOne.value[index],
697+
keyTwo.value[index],
698+
0,
699+
1
700+
)
701+
) as Vector;
702+
703+
return valueStart.map(
704+
(dimension, index) => dimension + valueDelta[index] * progress[index]
705+
);
706+
}
707+
708+
// Animate between numbers
709+
710+
if (
711+
typeof keyedAnimation === 'number' &&
712+
typeof keyOne.value === 'number' &&
713+
typeof keyTwo.value === 'number' &&
714+
typeof valueStart === 'number' &&
715+
typeof valueEnd === 'number' &&
716+
typeof valueDelta === 'number'
717+
) {
718+
// Remap the keyed value to our new values
719+
const progress = thisLayer.linear(
720+
keyedAnimation,
721+
keyOne.value,
722+
keyTwo.value,
723+
0,
724+
1
725+
) as number;
726+
727+
return thisLayer.add(valueStart, thisLayer.mul(valueDelta, progress));
728+
}
729+
}
730+
649731
return {
650732
attachKeys,
651733
bounceKeys,
@@ -669,6 +751,7 @@ function getFunctions(time: number = thisLayer.time) {
669751
maintainScale,
670752
offsetFromAnchor,
671753
addLineBreaks,
754+
remapKeys,
672755
};
673756
}
674757

0 commit comments

Comments
 (0)