e.stopPropagation()}>
+
e.stopPropagation()}
+ >
{/* Toolbar - above image */}
0}
- onToolChange={(tool) => setState(s => ({ ...s, tool }))}
- onColorChange={(color) => setState(s => ({ ...s, color }))}
- onStrokeSizeChange={(strokeSize) => setState(s => ({ ...s, strokeSize }))}
+ onToolChange={(tool) => setState((s) => ({ ...s, tool }))}
+ onColorChange={(color) => setState((s) => ({ ...s, color }))}
+ onStrokeSizeChange={(strokeSize) => setState((s) => ({ ...s, strokeSize }))}
onUndo={handleUndo}
onClear={handleClear}
onSave={handleAccept}
@@ -254,7 +259,9 @@ export const ImageAnnotator: React.FC = ({
{/* Accept hint */}
- Press Esc or Enter or click outside to accept
+ Press Esc or{' '}
+ Enter or click
+ outside to accept
diff --git a/packages/ui/components/ImageAnnotator/utils.ts b/packages/ui/components/ImageAnnotator/utils.ts
index e227fce..92b0cec 100644
--- a/packages/ui/components/ImageAnnotator/utils.ts
+++ b/packages/ui/components/ImageAnnotator/utils.ts
@@ -20,7 +20,7 @@ function getSvgPathFromStroke(stroke: number[][]): string {
acc.push(x0, y0, (x0 + x1) / 2, (y0 + y1) / 2);
return acc;
},
- ['M', ...stroke[0], 'Q']
+ ['M', ...stroke[0], 'Q'],
);
d.push('Z');
@@ -30,16 +30,16 @@ function getSvgPathFromStroke(stroke: number[][]): string {
/**
* Render a freehand pen stroke using perfect-freehand
*/
-export function renderPenStroke(
+function renderPenStroke(
ctx: CanvasRenderingContext2D,
points: Point[],
color: string,
size: number,
- scale = 1
+ scale = 1,
) {
if (points.length < 2) return;
- const scaledPoints = points.map(p => [p.x * scale, p.y * scale, p.pressure ?? 0.5]);
+ const scaledPoints = points.map((p) => [p.x * scale, p.y * scale, p.pressure ?? 0.5]);
const stroke = getStroke(scaledPoints, { ...STROKE_OPTIONS, size: size * scale });
const path = new Path2D(getSvgPathFromStroke(stroke));
@@ -50,13 +50,13 @@ export function renderPenStroke(
/**
* Render an arrow from start to end point
*/
-export function renderArrow(
+function renderArrow(
ctx: CanvasRenderingContext2D,
start: Point,
end: Point,
color: string,
size: number,
- scale = 1
+ scale = 1,
) {
const x1 = start.x * scale;
const y1 = start.y * scale;
@@ -82,11 +82,11 @@ export function renderArrow(
ctx.moveTo(x2, y2);
ctx.lineTo(
x2 - headLength * Math.cos(angle - Math.PI / 6),
- y2 - headLength * Math.sin(angle - Math.PI / 6)
+ y2 - headLength * Math.sin(angle - Math.PI / 6),
);
ctx.lineTo(
x2 - headLength * Math.cos(angle + Math.PI / 6),
- y2 - headLength * Math.sin(angle + Math.PI / 6)
+ y2 - headLength * Math.sin(angle + Math.PI / 6),
);
ctx.closePath();
ctx.fill();
@@ -95,13 +95,13 @@ export function renderArrow(
/**
* Render a circle from edge to edge (first click is one edge, drag to opposite edge)
*/
-export function renderCircle(
+function renderCircle(
ctx: CanvasRenderingContext2D,
start: Point,
end: Point,
color: string,
size: number,
- scale = 1
+ scale = 1,
) {
const x1 = start.x * scale;
const y1 = start.y * scale;
@@ -126,11 +126,7 @@ export function renderCircle(
/**
* Render a stroke based on its tool type
*/
-export function renderStroke(
- ctx: CanvasRenderingContext2D,
- stroke: Stroke,
- scale = 1
-) {
+export function renderStroke(ctx: CanvasRenderingContext2D, stroke: Stroke, scale = 1) {
if (stroke.points.length < 2) return;
switch (stroke.tool) {
@@ -138,10 +134,24 @@ export function renderStroke(
renderPenStroke(ctx, stroke.points, stroke.color, stroke.size, scale);
break;
case 'arrow':
- renderArrow(ctx, stroke.points[0], stroke.points[stroke.points.length - 1], stroke.color, stroke.size, scale);
+ renderArrow(
+ ctx,
+ stroke.points[0],
+ stroke.points[stroke.points.length - 1],
+ stroke.color,
+ stroke.size,
+ scale,
+ );
break;
case 'circle':
- renderCircle(ctx, stroke.points[0], stroke.points[stroke.points.length - 1], stroke.color, stroke.size, scale);
+ renderCircle(
+ ctx,
+ stroke.points[0],
+ stroke.points[stroke.points.length - 1],
+ stroke.color,
+ stroke.size,
+ scale,
+ );
break;
}
}
diff --git a/packages/ui/components/ImageThumbnail.tsx b/packages/ui/components/ImageThumbnail.tsx
index ba38c7e..6f1e247 100644
--- a/packages/ui/components/ImageThumbnail.tsx
+++ b/packages/ui/components/ImageThumbnail.tsx
@@ -1,4 +1,5 @@
-import React, { useState } from 'react';
+import type React from 'react';
+import { useState } from 'react';
/**
* Get the display URL for an image path or URL
@@ -40,9 +41,7 @@ export const ImageThumbnail: React.FC
= ({
return (
- {loading && !error && (
-
- )}
+ {loading && !error &&
}
{error ? (
= ({
}}
className="absolute -top-1 -right-1 w-4 h-4 bg-destructive text-destructive-foreground rounded-full opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center"
>
-