131 lines
2.9 KiB
TypeScript
131 lines
2.9 KiB
TypeScript
import type { AnimationPropertyPath, ElementAnimations } from "@/types/animation";
|
|
import type { Transform } from "@/types/timeline";
|
|
import { getColorValueAtTime, getNumberChannelValueAtTime } from "./interpolation";
|
|
import { getColorChannelForPath } from "./color-channel";
|
|
import { getNumberChannelForPath } from "./number-channel";
|
|
|
|
export function getElementLocalTime({
|
|
timelineTime,
|
|
elementStartTime,
|
|
elementDuration,
|
|
}: {
|
|
timelineTime: number;
|
|
elementStartTime: number;
|
|
elementDuration: number;
|
|
}): number {
|
|
const localTime = timelineTime - elementStartTime;
|
|
if (localTime <= 0) {
|
|
return 0;
|
|
}
|
|
|
|
if (localTime >= elementDuration) {
|
|
return elementDuration;
|
|
}
|
|
|
|
return localTime;
|
|
}
|
|
|
|
export function resolveTransformAtTime({
|
|
baseTransform,
|
|
animations,
|
|
localTime,
|
|
}: {
|
|
baseTransform: Transform;
|
|
animations: ElementAnimations | undefined;
|
|
localTime: number;
|
|
}): Transform {
|
|
const safeLocalTime = Math.max(0, localTime);
|
|
return {
|
|
position: {
|
|
x: getNumberChannelValueAtTime({
|
|
channel: getNumberChannelForPath({
|
|
animations,
|
|
propertyPath: "transform.position.x",
|
|
}),
|
|
time: safeLocalTime,
|
|
fallbackValue: baseTransform.position.x,
|
|
}),
|
|
y: getNumberChannelValueAtTime({
|
|
channel: getNumberChannelForPath({
|
|
animations,
|
|
propertyPath: "transform.position.y",
|
|
}),
|
|
time: safeLocalTime,
|
|
fallbackValue: baseTransform.position.y,
|
|
}),
|
|
},
|
|
scale: getNumberChannelValueAtTime({
|
|
channel: getNumberChannelForPath({
|
|
animations,
|
|
propertyPath: "transform.scale",
|
|
}),
|
|
time: safeLocalTime,
|
|
fallbackValue: baseTransform.scale,
|
|
}),
|
|
rotate: getNumberChannelValueAtTime({
|
|
channel: getNumberChannelForPath({
|
|
animations,
|
|
propertyPath: "transform.rotate",
|
|
}),
|
|
time: safeLocalTime,
|
|
fallbackValue: baseTransform.rotate,
|
|
}),
|
|
};
|
|
}
|
|
|
|
export function resolveOpacityAtTime({
|
|
baseOpacity,
|
|
animations,
|
|
localTime,
|
|
}: {
|
|
baseOpacity: number;
|
|
animations: ElementAnimations | undefined;
|
|
localTime: number;
|
|
}): number {
|
|
return getNumberChannelValueAtTime({
|
|
channel: getNumberChannelForPath({
|
|
animations,
|
|
propertyPath: "opacity",
|
|
}),
|
|
time: Math.max(0, localTime),
|
|
fallbackValue: baseOpacity,
|
|
});
|
|
}
|
|
|
|
export function resolveColorAtTime({
|
|
baseColor,
|
|
animations,
|
|
propertyPath,
|
|
localTime,
|
|
}: {
|
|
baseColor: string;
|
|
animations: ElementAnimations | undefined;
|
|
propertyPath: AnimationPropertyPath;
|
|
localTime: number;
|
|
}): string {
|
|
return getColorValueAtTime({
|
|
channel: getColorChannelForPath({ animations, propertyPath }),
|
|
time: Math.max(0, localTime),
|
|
fallbackValue: baseColor,
|
|
});
|
|
}
|
|
|
|
export function resolveVolumeAtTime({
|
|
baseVolume,
|
|
animations,
|
|
localTime,
|
|
}: {
|
|
baseVolume: number;
|
|
animations: ElementAnimations | undefined;
|
|
localTime: number;
|
|
}): number {
|
|
return getNumberChannelValueAtTime({
|
|
channel: getNumberChannelForPath({
|
|
animations,
|
|
propertyPath: "volume",
|
|
}),
|
|
time: Math.max(0, localTime),
|
|
fallbackValue: baseVolume,
|
|
});
|
|
}
|