73 lines
1.8 KiB
TypeScript
73 lines
1.8 KiB
TypeScript
import type {
|
|
AnimationPropertyPath,
|
|
ElementAnimations,
|
|
VectorAnimationChannel,
|
|
VectorValue,
|
|
} from "@/lib/animation/types";
|
|
|
|
export function isVectorValue(value: unknown): value is VectorValue {
|
|
return (
|
|
typeof value === "object" &&
|
|
value !== null &&
|
|
"x" in value &&
|
|
"y" in value &&
|
|
typeof (value as VectorValue).x === "number" &&
|
|
typeof (value as VectorValue).y === "number"
|
|
);
|
|
}
|
|
|
|
export function getVectorChannelForPath({
|
|
animations,
|
|
propertyPath,
|
|
}: {
|
|
animations: ElementAnimations | undefined;
|
|
propertyPath: AnimationPropertyPath;
|
|
}): VectorAnimationChannel | undefined {
|
|
const channel = animations?.channels[propertyPath];
|
|
if (!channel || channel.valueKind !== "vector") {
|
|
return undefined;
|
|
}
|
|
return channel;
|
|
}
|
|
|
|
export function getVectorChannelValueAtTime({
|
|
channel,
|
|
time,
|
|
fallbackValue,
|
|
}: {
|
|
channel: VectorAnimationChannel | undefined;
|
|
time: number;
|
|
fallbackValue: VectorValue;
|
|
}): VectorValue {
|
|
if (!channel || channel.keyframes.length === 0) {
|
|
return fallbackValue;
|
|
}
|
|
|
|
const keyframes = [...channel.keyframes].sort((a, b) => a.time - b.time);
|
|
const first = keyframes[0];
|
|
const last = keyframes[keyframes.length - 1];
|
|
|
|
if (!first || !last) return fallbackValue;
|
|
if (time <= first.time) return first.value;
|
|
if (time >= last.time) return last.value;
|
|
|
|
for (let i = 0; i < keyframes.length - 1; i++) {
|
|
const left = keyframes[i];
|
|
const right = keyframes[i + 1];
|
|
if (time < left.time || time > right.time) continue;
|
|
|
|
if (left.interpolation === "hold") return left.value;
|
|
|
|
const span = right.time - left.time;
|
|
if (span === 0) return right.value;
|
|
|
|
const t = (time - left.time) / span;
|
|
return {
|
|
x: left.value.x + (right.value.x - left.value.x) * t,
|
|
y: left.value.y + (right.value.y - left.value.y) * t,
|
|
};
|
|
}
|
|
|
|
return last.value;
|
|
}
|