136 lines
3.0 KiB
TypeScript
136 lines
3.0 KiB
TypeScript
import type {
|
|
AnimationPropertyPath,
|
|
ElementAnimations,
|
|
} from "@/lib/animation/types";
|
|
import type { Transform } from "@/lib/rendering";
|
|
import {
|
|
getColorValueAtTime,
|
|
getNumberChannelValueAtTime,
|
|
getVectorChannelValueAtTime,
|
|
} from "./interpolation";
|
|
import { getColorChannelForPath } from "./color-channel";
|
|
import { getNumberChannelForPath } from "./number-channel";
|
|
import { getVectorChannelForPath } from "./vector-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: getVectorChannelValueAtTime({
|
|
channel: getVectorChannelForPath({
|
|
animations,
|
|
propertyPath: "transform.position",
|
|
}),
|
|
time: safeLocalTime,
|
|
fallbackValue: baseTransform.position,
|
|
}),
|
|
scaleX: getNumberChannelValueAtTime({
|
|
channel: getNumberChannelForPath({
|
|
animations,
|
|
propertyPath: "transform.scaleX",
|
|
}),
|
|
time: safeLocalTime,
|
|
fallbackValue: baseTransform.scaleX,
|
|
}),
|
|
scaleY: getNumberChannelValueAtTime({
|
|
channel: getNumberChannelForPath({
|
|
animations,
|
|
propertyPath: "transform.scaleY",
|
|
}),
|
|
time: safeLocalTime,
|
|
fallbackValue: baseTransform.scaleY,
|
|
}),
|
|
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 resolveNumberAtTime({
|
|
baseValue,
|
|
animations,
|
|
propertyPath,
|
|
localTime,
|
|
}: {
|
|
baseValue: number;
|
|
animations: ElementAnimations | undefined;
|
|
propertyPath: AnimationPropertyPath;
|
|
localTime: number;
|
|
}): number {
|
|
return getNumberChannelValueAtTime({
|
|
channel: getNumberChannelForPath({ animations, propertyPath }),
|
|
time: Math.max(0, localTime),
|
|
fallbackValue: baseValue,
|
|
});
|
|
}
|
|
|
|
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,
|
|
});
|
|
}
|