summaryrefslogtreecommitdiff
path: root/apps/web/src/graphics/definitions/star.ts
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-04-20 11:31:17 +0200
committerMaze Winther <mazewinther@gmail.com>2026-04-20 11:31:17 +0200
commit3e89d2998588f8e35c524e523ba2ee853f0f6475 (patch)
tree57221f96c1259b3b07e3ddf8c1adefc502b9d8eb /apps/web/src/graphics/definitions/star.ts
parent729d10592f4e802f91c555c309ff3ba4b119f843 (diff)
downloadopencut-3e89d2998588f8e35c524e523ba2ee853f0f6475.tar.gz
refactor: restructure files to their domains, new preview overlay system, and dep graph
Diffstat (limited to 'apps/web/src/graphics/definitions/star.ts')
-rw-r--r--apps/web/src/graphics/definitions/star.ts109
1 files changed, 109 insertions, 0 deletions
diff --git a/apps/web/src/graphics/definitions/star.ts b/apps/web/src/graphics/definitions/star.ts
new file mode 100644
index 00000000..3aa40fee
--- /dev/null
+++ b/apps/web/src/graphics/definitions/star.ts
@@ -0,0 +1,109 @@
+import type { ParamDefinition } from "@/params";
+import { applyAlignedStroke } from "../stroke";
+import { STROKE_ALIGN_PARAM, type GraphicStrokeAlign } from "./shared";
+import type { GraphicDefinition } from "../types";
+
+interface StarParams {
+ fill: string;
+ stroke: string;
+ strokeWidth: number;
+ strokeAlign: GraphicStrokeAlign;
+ points: number;
+ depth: number;
+}
+
+const STAR_PARAMS: ParamDefinition<keyof StarParams & string>[] = [
+ {
+ key: "fill",
+ label: "Fill",
+ type: "color",
+ default: "#ffffff",
+ },
+ {
+ key: "stroke",
+ label: "Color",
+ type: "color",
+ default: "#000000",
+ group: "stroke",
+ },
+ {
+ key: "strokeWidth",
+ label: "Width",
+ type: "number",
+ default: 0,
+ min: 0,
+ max: 64,
+ step: 1,
+ shortLabel: "W",
+ group: "stroke",
+ },
+ STROKE_ALIGN_PARAM,
+ {
+ key: "points",
+ label: "Points",
+ type: "number",
+ default: 5,
+ min: 3,
+ max: 12,
+ step: 1,
+ shortLabel: "P",
+ },
+ {
+ key: "depth",
+ label: "Depth",
+ type: "number",
+ default: 45,
+ min: 1,
+ max: 99,
+ step: 1,
+ shortLabel: "D",
+ },
+];
+
+export const starGraphicDefinition: GraphicDefinition = {
+ id: "star",
+ name: "Star",
+ keywords: ["star", "sparkle", "burst"],
+ params: STAR_PARAMS,
+ render({ ctx, params, width, height }) {
+ const fill = String(params.fill ?? "#ffffff");
+ const stroke = String(params.stroke ?? "#000000");
+ const strokeWidth = Math.max(0, Number(params.strokeWidth ?? 0));
+ const strokeAlign = (params.strokeAlign ?? "center") as GraphicStrokeAlign;
+ const points = Math.max(3, Math.min(12, Math.round(Number(params.points ?? 5))));
+ const depth = Math.max(1, Math.min(99, Number(params.depth ?? 45))) / 100;
+ const inset = strokeAlign === "center" ? strokeWidth / 2 : 0;
+ const outerRadius = Math.max(1, Math.min(width, height) / 2 - inset);
+ const innerRadius = outerRadius * depth;
+ const centerX = width / 2;
+ const centerY = height / 2;
+
+ ctx.clearRect(0, 0, width, height);
+ const path = new Path2D();
+ for (let index = 0; index < points * 2; index++) {
+ const radius = index % 2 === 0 ? outerRadius : innerRadius;
+ const angle = -Math.PI / 2 + (index * Math.PI) / points;
+ const x = centerX + Math.cos(angle) * radius;
+ const y = centerY + Math.sin(angle) * radius;
+
+ if (index === 0) {
+ path.moveTo(x, y);
+ } else {
+ path.lineTo(x, y);
+ }
+ }
+ path.closePath();
+ ctx.fillStyle = fill;
+ ctx.fill(path);
+
+ if (strokeWidth > 0) {
+ applyAlignedStroke({
+ ctx,
+ path,
+ strokeWidth,
+ strokeAlign,
+ strokeColor: stroke,
+ });
+ }
+ },
+};