add app
This commit is contained in:
37
app/src/primitives/AnimatedEntities.ts
Normal file
37
app/src/primitives/AnimatedEntities.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { z } from "zod";
|
||||
import { BoxEntity, EllipseEntity, TextEntity } from "./Entities";
|
||||
import { AnimatedVec2 } from "./Values";
|
||||
|
||||
export const AnimationData = z.object({
|
||||
offset: z.number(),
|
||||
duration: z.number(),
|
||||
visible: z.boolean().optional().default(true),
|
||||
});
|
||||
|
||||
export const AnimatedBoxEntity = BoxEntity.extend({
|
||||
position: AnimatedVec2,
|
||||
size: AnimatedVec2,
|
||||
origin: AnimatedVec2,
|
||||
|
||||
animation_data: AnimationData,
|
||||
});
|
||||
|
||||
export const AnimatedTextEntity = TextEntity.extend({
|
||||
origin: AnimatedVec2,
|
||||
animation_data: AnimationData,
|
||||
});
|
||||
|
||||
export const AnimatedEllipseEntity = EllipseEntity.extend({
|
||||
radius: AnimatedVec2,
|
||||
position: AnimatedVec2,
|
||||
origin: AnimatedVec2,
|
||||
animation_data: AnimationData,
|
||||
});
|
||||
|
||||
export const AnimatedEntity = z.discriminatedUnion("type", [
|
||||
AnimatedBoxEntity,
|
||||
AnimatedTextEntity,
|
||||
AnimatedEllipseEntity,
|
||||
]);
|
||||
|
||||
export const AnimatedEntities = z.array(AnimatedEntity);
|
||||
40
app/src/primitives/Entities.ts
Normal file
40
app/src/primitives/Entities.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { z } from "zod";
|
||||
import { Vec2 } from "./Values";
|
||||
import { Paint, TextPaint } from "./Paint";
|
||||
|
||||
const EntityTypeOptions = ["Text", "Ellipse", "Box"] as const;
|
||||
|
||||
export const EntityType = z.enum(EntityTypeOptions);
|
||||
|
||||
export const GeometryEntity = z.object({
|
||||
paint: Paint,
|
||||
});
|
||||
|
||||
export const BoxEntity = GeometryEntity.extend({
|
||||
type: z.literal(EntityType.Enum.Box),
|
||||
size: Vec2,
|
||||
position: Vec2,
|
||||
origin: Vec2,
|
||||
});
|
||||
|
||||
export const EllipseEntity = GeometryEntity.extend({
|
||||
type: z.literal(EntityType.Enum.Ellipse),
|
||||
radius: Vec2,
|
||||
position: Vec2,
|
||||
origin: Vec2,
|
||||
});
|
||||
|
||||
export const TextEntity = z.object({
|
||||
type: z.literal(EntityType.Enum.Text),
|
||||
paint: TextPaint,
|
||||
origin: Vec2,
|
||||
text: z.string(),
|
||||
});
|
||||
|
||||
export const Entity = z.discriminatedUnion("type", [
|
||||
BoxEntity,
|
||||
EllipseEntity,
|
||||
TextEntity,
|
||||
]);
|
||||
|
||||
export const Entities = z.array(Entity);
|
||||
53
app/src/primitives/Interpolation.ts
Normal file
53
app/src/primitives/Interpolation.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { z } from "zod";
|
||||
|
||||
const InterpolationTypeOptions = [
|
||||
"Linear",
|
||||
"Spring",
|
||||
"EasingFunction",
|
||||
] as const;
|
||||
|
||||
const EasingFunctionOptions = [
|
||||
"QuintOut",
|
||||
"QuintIn",
|
||||
"QuintInOut",
|
||||
"CircOut",
|
||||
"CircIn",
|
||||
"CircInOut",
|
||||
"CubicOut",
|
||||
"CubicIn",
|
||||
"CubicInOut",
|
||||
"ExpoOut",
|
||||
"ExpoIn",
|
||||
"ExpoInOut",
|
||||
"QuadOut",
|
||||
"QuadIn",
|
||||
"QuadInOut",
|
||||
"QuartOut",
|
||||
"QuartIn",
|
||||
"QuartInOut",
|
||||
] as const;
|
||||
|
||||
export const EasingFunction = z.enum(EasingFunctionOptions);
|
||||
export const InterpolationType = z.enum(InterpolationTypeOptions);
|
||||
|
||||
export const LinearInterpolation = z.object({
|
||||
type: z.literal(InterpolationType.Enum.Linear),
|
||||
});
|
||||
|
||||
export const EasingFunctionInterpolation = z.object({
|
||||
type: z.literal(InterpolationType.Enum.EasingFunction),
|
||||
easing_function: EasingFunction,
|
||||
});
|
||||
|
||||
export const SpringInterpolation = z.object({
|
||||
mass: z.number(),
|
||||
damping: z.number(),
|
||||
stiffness: z.number(),
|
||||
type: z.literal(InterpolationType.Enum.Spring),
|
||||
});
|
||||
|
||||
export const Interpolation = z.discriminatedUnion("type", [
|
||||
SpringInterpolation,
|
||||
EasingFunctionInterpolation,
|
||||
LinearInterpolation,
|
||||
]);
|
||||
12
app/src/primitives/Keyframe.ts
Normal file
12
app/src/primitives/Keyframe.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { z } from "zod";
|
||||
import { Interpolation } from "./Interpolation";
|
||||
|
||||
export const Keyframe = z.object({
|
||||
value: z.number(),
|
||||
offset: z.number(),
|
||||
interpolation: z.optional(Interpolation),
|
||||
});
|
||||
|
||||
export const Keyframes = z.object({
|
||||
values: z.array(Keyframe),
|
||||
});
|
||||
49
app/src/primitives/Paint.ts
Normal file
49
app/src/primitives/Paint.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const Color = z.object({
|
||||
value: z.array(z.number().min(0).max(255)).max(4),
|
||||
});
|
||||
|
||||
const PaintStyleTypeOptions = ["Fill", "Stroke"] as const;
|
||||
|
||||
export const PaintStyleType = z.enum(PaintStyleTypeOptions);
|
||||
|
||||
const ColorWithDefault = Color.optional().default({ value: [0, 0, 0, 1] });
|
||||
|
||||
export const StrokeStyle = z.object({
|
||||
width: z.number().min(0).optional().default(10),
|
||||
color: ColorWithDefault,
|
||||
type: z.literal(PaintStyleType.Enum.Stroke),
|
||||
});
|
||||
|
||||
export const FillStyle = z.object({
|
||||
color: ColorWithDefault,
|
||||
type: z.literal(PaintStyleType.Enum.Fill),
|
||||
});
|
||||
|
||||
export const TextAlign = z.enum(["Left", "Center", "Right"]);
|
||||
|
||||
export const PaintStyle = z.discriminatedUnion("type", [
|
||||
StrokeStyle,
|
||||
FillStyle,
|
||||
]);
|
||||
|
||||
export const Paint = z.object({
|
||||
style: PaintStyle,
|
||||
});
|
||||
|
||||
export const TextPaint = z.object({
|
||||
style: PaintStyle,
|
||||
align: TextAlign,
|
||||
size: z.number().min(0),
|
||||
});
|
||||
|
||||
/* const NestedFillStyle = FillStyle.omit({ type: true }).default({});
|
||||
const NestedStrokeStyle = StrokeStyle.omit({ type: true }).default({});
|
||||
|
||||
export const StrokeAndFillStyle = z.object({
|
||||
color: ColorWithDefault,
|
||||
type: z.literal(PaintStyleType.Enum.StrokeAndFill),
|
||||
fill: NestedFillStyle,
|
||||
stroke: NestedStrokeStyle,
|
||||
}); */
|
||||
14
app/src/primitives/Timeline.ts
Normal file
14
app/src/primitives/Timeline.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { z } from "zod";
|
||||
import { AnimatedEntities } from "./AnimatedEntities";
|
||||
|
||||
export const RenderState = z.object({
|
||||
curr_frame: z.number(),
|
||||
});
|
||||
|
||||
export const Timeline = z.object({
|
||||
entities: AnimatedEntities,
|
||||
render_state: RenderState,
|
||||
duration: z.number(),
|
||||
fps: z.number().int(),
|
||||
size: z.array(z.number().int()).length(2),
|
||||
});
|
||||
67
app/src/primitives/Values.ts
Normal file
67
app/src/primitives/Values.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { z } from "zod";
|
||||
import { Keyframes } from "./Keyframe";
|
||||
import { Interpolation } from "./Interpolation";
|
||||
|
||||
export const Vec2 = z.array(z.number()).length(2);
|
||||
|
||||
export const AnimatedNumber = z.object({
|
||||
keyframes: Keyframes,
|
||||
});
|
||||
|
||||
export const AnimatedVec2 = z.object({
|
||||
keyframes: z.array(AnimatedNumber).length(2),
|
||||
});
|
||||
|
||||
export function staticAnimatedNumber(
|
||||
number: number
|
||||
): z.infer<typeof AnimatedNumber> {
|
||||
return {
|
||||
keyframes: {
|
||||
values: [
|
||||
{
|
||||
interpolation: {
|
||||
type: "Linear",
|
||||
},
|
||||
value: number,
|
||||
offset: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function staticAnimatedVec2(
|
||||
x: number,
|
||||
y: number
|
||||
): z.infer<typeof AnimatedVec2> {
|
||||
return {
|
||||
keyframes: [
|
||||
{
|
||||
keyframes: {
|
||||
values: [
|
||||
{
|
||||
interpolation: {
|
||||
type: "Linear",
|
||||
},
|
||||
value: x,
|
||||
offset: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
keyframes: {
|
||||
values: [
|
||||
{
|
||||
interpolation: {
|
||||
type: "Linear",
|
||||
},
|
||||
value: y,
|
||||
offset: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user