100 lines
2.3 KiB
TypeScript
100 lines
2.3 KiB
TypeScript
import type {
|
|
AnimationBindingInstance,
|
|
AnimationPath,
|
|
ElementAnimations,
|
|
ScalarAnimationChannel,
|
|
ScalarGraphChannel,
|
|
ScalarGraphKeyframeContext,
|
|
} from "@/lib/animation/types";
|
|
|
|
export interface EditableScalarChannels {
|
|
binding: AnimationBindingInstance;
|
|
channels: ScalarGraphChannel[];
|
|
}
|
|
|
|
function isScalarAnimationChannel(
|
|
channel: ElementAnimations["channels"][string],
|
|
): channel is ScalarAnimationChannel {
|
|
return channel?.kind === "scalar";
|
|
}
|
|
|
|
export function getEditableScalarChannels({
|
|
animations,
|
|
propertyPath,
|
|
}: {
|
|
animations: ElementAnimations | undefined;
|
|
propertyPath: AnimationPath;
|
|
}): EditableScalarChannels | null {
|
|
const binding = animations?.bindings[propertyPath];
|
|
if (!binding) {
|
|
return null;
|
|
}
|
|
|
|
const channels = binding.components.flatMap((component) => {
|
|
const channel = animations?.channels[component.channelId];
|
|
if (!isScalarAnimationChannel(channel)) {
|
|
return [];
|
|
}
|
|
|
|
return [
|
|
{
|
|
propertyPath,
|
|
componentKey: component.key,
|
|
channelId: component.channelId,
|
|
channel,
|
|
} satisfies ScalarGraphChannel,
|
|
];
|
|
});
|
|
|
|
return { binding, channels };
|
|
}
|
|
|
|
export function getEditableScalarChannel({
|
|
animations,
|
|
propertyPath,
|
|
componentKey,
|
|
}: {
|
|
animations: ElementAnimations | undefined;
|
|
propertyPath: AnimationPath;
|
|
componentKey: string;
|
|
}): ScalarGraphChannel | null {
|
|
const result = getEditableScalarChannels({ animations, propertyPath });
|
|
return result?.channels.find((channel) => channel.componentKey === componentKey) ?? null;
|
|
}
|
|
|
|
export function getScalarKeyframeContext({
|
|
animations,
|
|
propertyPath,
|
|
componentKey,
|
|
keyframeId,
|
|
}: {
|
|
animations: ElementAnimations | undefined;
|
|
propertyPath: AnimationPath;
|
|
componentKey: string;
|
|
keyframeId: string;
|
|
}): ScalarGraphKeyframeContext | null {
|
|
const scalarChannel = getEditableScalarChannel({
|
|
animations,
|
|
propertyPath,
|
|
componentKey,
|
|
});
|
|
if (!scalarChannel) {
|
|
return null;
|
|
}
|
|
|
|
const keyframeIndex = scalarChannel.channel.keys.findIndex(
|
|
(keyframe) => keyframe.id === keyframeId,
|
|
);
|
|
if (keyframeIndex < 0) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
...scalarChannel,
|
|
keyframe: scalarChannel.channel.keys[keyframeIndex],
|
|
keyframeIndex,
|
|
previousKey: scalarChannel.channel.keys[keyframeIndex - 1] ?? null,
|
|
nextKey: scalarChannel.channel.keys[keyframeIndex + 1] ?? null,
|
|
};
|
|
}
|