From 82f938d8622b9b13ecf739a38507f86f4d043f20 Mon Sep 17 00:00:00 2001
From: Sebastian Mohr <sebastian@mohrenclan.de>
Date: Wed, 19 Mar 2025 12:50:17 +0100
Subject: [PATCH] Added a drawScale function

---
 packages/snips/src/uprp/stampy.ts | 112 ++++++++++++++++++++++++++++--
 1 file changed, 108 insertions(+), 4 deletions(-)

diff --git a/packages/snips/src/uprp/stampy.ts b/packages/snips/src/uprp/stampy.ts
index bdcb1fb0..299cf049 100644
--- a/packages/snips/src/uprp/stampy.ts
+++ b/packages/snips/src/uprp/stampy.ts
@@ -190,16 +190,120 @@ export class StampySnip extends BaseSnip {
         return this.stampy.measurement.volume;
     }
 
-    // TODO: Implement this method
+    // TODO: Make this dynamic
     get width(): number {
-        return 0;
+        return 700;
     }
     get height(): number {
-        return 0;
+        return 700;
+    }
+
+    private computeScale(): number {
+        // compute scale from given data to fit into
+        // the width and height of the canvas
+        // TODO: Implement this
+        return 150;
     }
 
     public render(ctx: RenderContext): void {
-        throw new Error("Render method not implemented.");
+        // Draw rect around the area
+        ctx.rect(0, 0, this.width, this.height);
+        ctx.stroke();
+
+        // Render sample circle
+        const s = this.computeScale();
+        this.drawCircle(
+            ctx,
+            this.width / 2,
+            this.height / 2,
+            (this.volume.diameter / 2) * s,
+            {
+                stroke: "black",
+                fill: "red",
+                fill_alpha: 0.5,
+            },
+        );
+
+        // Render scale
+        this.drawScale(ctx, s);
+    }
+
+    private drawCircle(
+        ctx: RenderContext,
+        x: number,
+        y: number,
+        radius: number,
+        style: {
+            stroke: string;
+            fill?: string;
+            fill_alpha?: number;
+            stroke_alpha?: number;
+        },
+    ) {
+        if (style.fill_alpha === undefined) {
+            style.fill_alpha = 1;
+        }
+        if (style.stroke_alpha === undefined) {
+            style.stroke_alpha = 1;
+        }
+
+        // Draw fill if fill color is defined
+        if (style.fill) {
+            ctx.save();
+            ctx.beginPath();
+            ctx.globalAlpha = style.fill_alpha;
+            ctx.fillStyle = style.fill;
+            ctx.arc(x, y, radius, 0, 2 * Math.PI);
+            ctx.fill();
+            ctx.restore();
+        }
+
+        // Draw stroke
+        ctx.save();
+        ctx.globalAlpha = style.stroke_alpha;
+        ctx.strokeStyle = style.stroke;
+        ctx.beginPath();
+        ctx.arc(x, y, radius, 0, 2 * Math.PI);
+        ctx.closePath();
+        ctx.stroke();
+        ctx.restore();
+    }
+
+    /** Draws a 1mm scale
+     * @param ctx - The rendering context.
+     * @param scale - The scale factor to use (i.e. how many pixels is 1mm).
+     *
+     * If the scale is too small, the scale will be multiplied until it is
+     * at least 150px.
+     */
+    private drawScale(ctx: RenderContext, scale: number) {
+        let mm = 1;
+        let s = scale;
+        while (s < 150) {
+            mm *= 2;
+            s *= 2;
+        }
+
+        // pos
+        const padding = 10;
+        const rectHeight = 5;
+        const x = this.width - s - padding;
+        const y = this.height - rectHeight - padding - 18; //18=font size
+
+        // Render scale rect
+        ctx.globalAlpha = 0.8;
+        ctx.fillStyle = "#000";
+        ctx.beginPath();
+        ctx.fillRect(x, y, s, rectHeight);
+        ctx.stroke();
+
+        // Render text
+        ctx.globalAlpha = 1;
+        ctx.fillStyle = "#000";
+        ctx.font = "18px Arial";
+        ctx.textBaseline = "top";
+        const ts = ctx.measureText(`${mm} mm`);
+        ctx.fillText(`${mm} mm`, x + s / 2 - ts.width / 2, y + rectHeight);
     }
 }
 
-- 
GitLab