summaryrefslogtreecommitdiff
path: root/apps/web/src/masks/registry.ts
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-04-29 18:27:21 +0200
committerMaze Winther <mazewinther@gmail.com>2026-05-02 03:27:23 +0200
commitae1292a14bf5c29544a5f7a49e65b994410f87de (patch)
tree5fd3b7fcef3d87d6fcdbe38bf34b99d32038b41f /apps/web/src/masks/registry.ts
parent6ea5a156b6b7f609354a4563cfb2d00ec7f41811 (diff)
downloadopencut-ae1292a14bf5c29544a5f7a49e65b994410f87de.tar.gz
refactor: make mask renderer dispatch explicit
Made-with: Cursor
Diffstat (limited to 'apps/web/src/masks/registry.ts')
-rw-r--r--apps/web/src/masks/registry.ts68
1 files changed, 26 insertions, 42 deletions
diff --git a/apps/web/src/masks/registry.ts b/apps/web/src/masks/registry.ts
index 0bcf1cf0..64ab2f60 100644
--- a/apps/web/src/masks/registry.ts
+++ b/apps/web/src/masks/registry.ts
@@ -2,11 +2,11 @@ import { MAX_FEATHER } from "@/masks/feather";
import type { ParamDefinition } from "@/params";
import type {
BaseMaskParams,
+ Mask,
MaskDefaultContext,
MaskDefinition,
- MaskInteractionResult,
- MaskSnapArgs,
- MaskSnapResult,
+ MaskParamUpdateArgs,
+ MaskRenderer,
MaskType,
} from "@/masks/types";
import type { HugeiconsIconProps } from "@hugeicons/react";
@@ -17,6 +17,16 @@ export type MaskIconProps = {
strokeWidth?: number;
};
+type RegisteredMaskWithoutId = Mask extends infer TMask
+ ? TMask extends Mask
+ ? Omit<TMask, "id">
+ : never
+ : never;
+
+export type MaskDefinitionForRegistration = {
+ [TType in MaskType]: MaskDefinition<TType>;
+}[MaskType];
+
const BASE_MASK_PARAM_DEFINITIONS: ParamDefinition<
keyof BaseMaskParams & string
>[] = [
@@ -50,28 +60,15 @@ const BASE_MASK_PARAM_DEFINITIONS: ParamDefinition<
export interface RegisteredMaskDefinition {
type: MaskType;
name: string;
- features: MaskDefinition<BaseMaskParams>["features"];
+ features: MaskDefinition["features"];
params: ParamDefinition<string>[];
- renderer: MaskDefinition<BaseMaskParams>["renderer"];
- interaction: {
- getInteraction(args: {
- params: BaseMaskParams;
- bounds: Parameters<
- MaskDefinition<BaseMaskParams>["interaction"]["getInteraction"]
- >[0]["bounds"];
- displayScale: number;
- scaleX: number;
- scaleY: number;
- }): MaskInteractionResult;
- snap?(args: MaskSnapArgs<BaseMaskParams>): MaskSnapResult<BaseMaskParams>;
- };
- isActive?: (params: BaseMaskParams) => boolean;
- buildDefault(
- context: MaskDefaultContext,
- ): ReturnType<MaskDefinition<BaseMaskParams>["buildDefault"]>;
+ renderer: MaskRenderer<BaseMaskParams>;
+ interaction: MaskDefinition["interaction"];
+ isActive?(params: BaseMaskParams): boolean;
+ buildDefault(context: MaskDefaultContext): RegisteredMaskWithoutId;
computeParamUpdate(
- args: Parameters<MaskDefinition<BaseMaskParams>["computeParamUpdate"]>[0],
- ): ReturnType<MaskDefinition<BaseMaskParams>["computeParamUpdate"]>;
+ args: MaskParamUpdateArgs<BaseMaskParams>,
+ ): ReturnType<MaskDefinition["computeParamUpdate"]>;
icon: MaskIconProps;
}
@@ -83,11 +80,11 @@ export class MasksRegistry extends DefinitionRegistry<
super("mask");
}
- registerMask<TParams extends BaseMaskParams>({
+ registerMask({
definition,
icon,
}: {
- definition: MaskDefinition<TParams>;
+ definition: MaskDefinitionForRegistration;
icon: MaskIconProps;
}): void {
const withBaseParams: RegisteredMaskDefinition = {
@@ -96,23 +93,10 @@ export class MasksRegistry extends DefinitionRegistry<
features: definition.features,
params: [...definition.params, ...BASE_MASK_PARAM_DEFINITIONS],
renderer: definition.renderer,
- interaction: {
- getInteraction(args) {
- return definition.interaction.getInteraction(args as never);
- },
- snap: definition.interaction.snap
- ? (args) => definition.interaction.snap?.(args as never) as never
- : undefined,
- },
- isActive: definition.isActive
- ? (params) => definition.isActive?.(params as TParams) ?? true
- : undefined,
- buildDefault(context) {
- return definition.buildDefault(context);
- },
- computeParamUpdate(args) {
- return definition.computeParamUpdate(args as never);
- },
+ interaction: definition.interaction,
+ isActive: definition.isActive,
+ buildDefault: definition.buildDefault,
+ computeParamUpdate: definition.computeParamUpdate,
icon,
};
this.register({