195 lines
5.0 KiB
TypeScript
195 lines
5.0 KiB
TypeScript
import { z } from "zod";
|
|
import {
|
|
BaseEntity,
|
|
EllipseEntity,
|
|
EntityType,
|
|
RectEntity,
|
|
TextEntity,
|
|
} from "./Entities";
|
|
import { AnimatedTransform, AnimatedVec2 } from "./Values";
|
|
import { TextPaint } from "./Paint";
|
|
import { AnimatedProperties } from "./AnimatedProperty";
|
|
|
|
export const AnimationData = z.object({
|
|
offset: z.number(),
|
|
duration: z.number(),
|
|
visible: z.boolean().optional().default(true),
|
|
});
|
|
|
|
export const AnimatedStaggeredTextEntity = BaseEntity.extend({
|
|
/** Transform applied to the whole layer. */
|
|
transform: AnimatedTransform,
|
|
/** The staggered delay that is applied for each letter. Gets multiplied by the index of the letter. */
|
|
stagger: z.number().min(0),
|
|
/** These properties get applied to each letter */
|
|
letter: z.object({
|
|
transform: AnimatedTransform,
|
|
paint: TextPaint,
|
|
}),
|
|
text: z.string(),
|
|
origin: AnimatedVec2,
|
|
animation_data: AnimationData,
|
|
type: z.literal(EntityType.Enum.StaggeredText),
|
|
});
|
|
|
|
export const AnimatedRectEntity = RectEntity.extend({
|
|
position: AnimatedVec2,
|
|
size: AnimatedVec2,
|
|
origin: AnimatedVec2,
|
|
transform: AnimatedTransform.optional(),
|
|
animation_data: AnimationData,
|
|
});
|
|
|
|
export const AnimatedTextEntity = TextEntity.extend({
|
|
origin: AnimatedVec2,
|
|
transform: AnimatedTransform.optional(),
|
|
animation_data: AnimationData,
|
|
});
|
|
|
|
export const AnimatedEllipseEntity = EllipseEntity.extend({
|
|
radius: AnimatedVec2,
|
|
position: AnimatedVec2,
|
|
origin: AnimatedVec2,
|
|
transform: AnimatedTransform.optional(),
|
|
animation_data: AnimationData,
|
|
});
|
|
|
|
export const AnimatedEntity = z.discriminatedUnion("type", [
|
|
AnimatedRectEntity,
|
|
AnimatedTextEntity,
|
|
AnimatedStaggeredTextEntity,
|
|
AnimatedEllipseEntity,
|
|
]);
|
|
|
|
export const AnimatedEntities = z.array(AnimatedEntity);
|
|
|
|
export function animatedTransformToAnimatedProperties(
|
|
animatedTransform: z.input<typeof AnimatedTransform>,
|
|
basePath?: string
|
|
): z.input<typeof AnimatedProperties> {
|
|
return [
|
|
{
|
|
animatedValue: animatedTransform.translate,
|
|
label: "Translation",
|
|
propertyPath: basePath
|
|
? basePath + ".transform.translate"
|
|
: "transform.translate",
|
|
},
|
|
{
|
|
animatedValue: animatedTransform.rotate,
|
|
label: "Rotation",
|
|
propertyPath: basePath
|
|
? basePath + ".transform.rotate"
|
|
: "transform.rotate",
|
|
},
|
|
{
|
|
animatedValue: animatedTransform.scale,
|
|
label: "Scale",
|
|
propertyPath: basePath
|
|
? basePath + ".transform.scale"
|
|
: "transform.scale",
|
|
},
|
|
{
|
|
animatedValue: animatedTransform.skew,
|
|
label: "Skew",
|
|
propertyPath: basePath ? basePath + ".transform.skew" : "transform.skew",
|
|
},
|
|
];
|
|
}
|
|
|
|
export function getAnimatedPropertiesByAnimatedEntity(
|
|
animatedEntity: z.input<typeof AnimatedEntity>
|
|
) {
|
|
const animatedProperties: z.input<typeof AnimatedProperties> = [];
|
|
|
|
switch (animatedEntity.type) {
|
|
case "Ellipse":
|
|
animatedProperties.push({
|
|
propertyPath: "origin",
|
|
animatedValue: animatedEntity.origin,
|
|
label: "Origin",
|
|
});
|
|
animatedProperties.push({
|
|
propertyPath: "radius",
|
|
animatedValue: animatedEntity.radius,
|
|
label: "Radius",
|
|
});
|
|
|
|
if (animatedEntity.transform) {
|
|
animatedProperties.push(
|
|
...animatedTransformToAnimatedProperties(animatedEntity.transform)
|
|
);
|
|
}
|
|
|
|
break;
|
|
|
|
case "Rect":
|
|
animatedProperties.push({
|
|
propertyPath: "origin",
|
|
animatedValue: animatedEntity.origin,
|
|
label: "Origin",
|
|
});
|
|
animatedProperties.push({
|
|
propertyPath: "size",
|
|
animatedValue: animatedEntity.size,
|
|
label: "Size",
|
|
});
|
|
|
|
if (animatedEntity.transform) {
|
|
animatedProperties.push(
|
|
...animatedTransformToAnimatedProperties(animatedEntity.transform)
|
|
);
|
|
}
|
|
break;
|
|
|
|
case "StaggeredText":
|
|
animatedProperties.push({
|
|
propertyPath: "origin",
|
|
animatedValue: animatedEntity.origin,
|
|
label: "Origin",
|
|
});
|
|
|
|
if (animatedEntity.transform) {
|
|
animatedProperties.push(
|
|
...animatedTransformToAnimatedProperties(animatedEntity.transform)
|
|
);
|
|
}
|
|
|
|
if (animatedEntity.letter.transform) {
|
|
animatedProperties.push(
|
|
...animatedTransformToAnimatedProperties(
|
|
animatedEntity.letter.transform,
|
|
"letter"
|
|
)
|
|
);
|
|
}
|
|
break;
|
|
|
|
case "Text":
|
|
animatedProperties.push({
|
|
propertyPath: "origin",
|
|
animatedValue: animatedEntity.origin,
|
|
label: "Origin",
|
|
});
|
|
|
|
if (animatedEntity.transform) {
|
|
animatedProperties.push(
|
|
...animatedTransformToAnimatedProperties(animatedEntity.transform)
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return animatedProperties;
|
|
}
|
|
|
|
export function getAnimatedPropertiesByAnimatedEnties(
|
|
animatedEntities: z.input<typeof AnimatedEntities>
|
|
) {
|
|
const animatedProperties: z.input<typeof AnimatedProperties> = [];
|
|
|
|
animatedEntities.forEach((aEnt) => {
|
|
animatedProperties.push(...getAnimatedPropertiesByAnimatedEntity(aEnt));
|
|
});
|
|
}
|