frame.image 1.4.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"Designer.d.ts","sourceRoot":"","sources":["../src/Designer.tsx"],"names":[],"mappings":"AAcA,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAC9B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,2CAiQA"}
1
+ {"version":3,"file":"Designer.d.ts","sourceRoot":"","sources":["../src/Designer.tsx"],"names":[],"mappings":"AAeA,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAC9B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,2CA+QA"}
package/dist/Designer.js CHANGED
@@ -11,6 +11,7 @@ import { Polygon } from './Polygon';
11
11
  import { Point } from './Point';
12
12
  import { Finish } from './Finish';
13
13
  import { Start } from './Start';
14
+ import { Akima, AkimaPoint, createRT1 } from 'frame.akima';
14
15
  export function Designer(props) {
15
16
  const nrPoints = props.nrPoints || 128;
16
17
  const width = 600;
@@ -22,6 +23,9 @@ export function Designer(props) {
22
23
  const [axis, setAxis] = useState({});
23
24
  const [rotationAngle, setRotationAngle] = useState(0);
24
25
  const [coords, setCoords] = useState(new Polygon([], universeCenter));
26
+ const [scaledSL, setScaledSL] = useState(undefined);
27
+ const [scaledSH, setScaledSH] = useState(undefined);
28
+ const [trademarkCenter, setTrademarkCenter] = useState(undefined);
25
29
  const [show, setShow] = useState({
26
30
  catmullRomPoints: true,
27
31
  catmullRom: true,
@@ -60,7 +64,7 @@ export function Designer(props) {
60
64
  };
61
65
  function onCloseScaleForm() {
62
66
  // if (cont) {
63
- // props.command(ACTION.SCALE_FORM);
67
+ sendCommand(ACTION.SCALE_FORM);
64
68
  // }
65
69
  // setShowModalScaleForm(false);
66
70
  }
@@ -86,14 +90,13 @@ export function Designer(props) {
86
90
  setScalingEnabled(false);
87
91
  sendCommand(ACTION.UNDO_TRANSFORMATION);
88
92
  };
89
- const onClose = (pol) => () => {
90
- const catmullRomPolygonRT1 = pol.createCatmullRomPoints(128);
91
- catmullRomPolygonRT1.assertEquiDistantAngles();
92
- const rt1 = catmullRomPolygonRT1.createRT1();
93
- const catmullRomPolygonTR1 = pol.createCatmullRomPoints(1000);
94
- catmullRomPolygonTR1.assertEquiDistantAngles();
95
- const tr1 = catmullRomPolygonTR1.createTR1();
96
- console.log(`TR1: ${tr1}`);
93
+ const onClose = (pol, trademark) => () => {
94
+ const pts = pol.Points.map((pt) => new AkimaPoint(pt.X, pt.Y));
95
+ const { points } = Akima.createPointsByAkima(pts, 128, false);
96
+ const rt1 = createRT1(points);
97
+ if (trademark) {
98
+ console.log(`trademark is now defined at [${trademark.X}, ${trademark.Y}]`);
99
+ }
97
100
  props.onClose(rt1);
98
101
  };
99
102
  const wCol1 = 1;
@@ -135,7 +138,7 @@ export function Designer(props) {
135
138
  boxSizing: 'border-box',
136
139
  backgroundColor: 'rgb(255, 0, 0)',
137
140
  px: '5px', // horizontal padding of 5px
138
- }, children: _jsx(Start, { machine: currentMachine, onReset: onClickReset, onAfterLoadImage: onAfterLoadImage, onAfterLoadPoints: onAfterLoadPoints, onAfterDefinePoints: onAfterDefinePoints }) }), _jsx(Box, { id: "id.box.canvas", sx: {
141
+ }, children: _jsx(Start, { origin: universeCenter, machine: currentMachine, onReset: onClickReset, onAfterLoadImage: onAfterLoadImage, onAfterLoadPoints: onAfterLoadPoints, onAfterDefinePoints: onAfterDefinePoints }) }), _jsx(Box, { id: "id.box.canvas", sx: {
139
142
  display: 'flex',
140
143
  flexDirection: 'column',
141
144
  flex: wCol2,
@@ -143,7 +146,7 @@ export function Designer(props) {
143
146
  height: '100%',
144
147
  boxSizing: 'border-box',
145
148
  backgroundColor: 'rgb(173, 216, 230)', // lightblue in rgb
146
- }, children: _jsx(DrawCanvas, { machine: currentMachine, command: sendCommand, width: width, height: height, status: { status, setStatus }, show: show, axis: { axis, setAxis }, imageUrl: imageUrl, coords: { coords, setCoords }, imageCoords: { imageCoords, setImageCoords }, rotation: { rotationAngle, setRotationAngle }, catmullRomPoints: { catmullRomPoints, setCatmullRomPoints } }) }), _jsx(Box, { id: "id.box.ScaleForm", sx: {
149
+ }, children: _jsx(DrawCanvas, { machine: currentMachine, command: sendCommand, width: width, height: height, status: { status, setStatus }, show: show, axis: { axis, setAxis }, imageUrl: imageUrl, coords: { coords, setCoords }, trademarkCenter: { trademarkCenter, setTrademarkCenter }, imageCoords: { imageCoords, setImageCoords }, rotation: { rotationAngle, setRotationAngle }, scaledSL: scaledSL, scaledSH: scaledSH, catmullRomPoints: { catmullRomPoints, setCatmullRomPoints } }) }), _jsx(Box, { id: "id.box.ScaleForm", sx: {
147
150
  display: 'flex',
148
151
  flexDirection: 'column',
149
152
  flex: wCol3,
@@ -153,9 +156,9 @@ export function Designer(props) {
153
156
  boxSizing: 'border-box',
154
157
  overflow: 'auto',
155
158
  backgroundColor: 'rgb(144, 238, 144)', // lightgreen in rgb
156
- }, children: _jsx(ScaleForm, { title: "Apply Scale", currentPoints: currentMachine.context.nrPoints, coords: { coords, setCoords }, disabled: !scalingEnabled, onCloseCancel: handleCloseScaleFormCancel, onCloseContinue: handleCloseScaleFormContinue }) })] }), _jsx(Box, { id: "id.box.2", sx: {
159
+ }, children: _jsx(ScaleForm, { title: "Apply Scale", currentPoints: currentMachine.context.nrPoints, coords: { coords, setCoords }, scaledSL: { value: scaledSL, setValue: setScaledSL }, scaledSH: { value: scaledSH, setValue: setScaledSH }, disabled: !scalingEnabled, onCloseCancel: handleCloseScaleFormCancel, onCloseContinue: handleCloseScaleFormContinue }) })] }), _jsx(Box, { id: "id.box.2", sx: {
157
160
  height: '20%',
158
161
  width: '100%',
159
162
  overflow: 'auto',
160
- }, children: _jsx(Finish, { universeCenter: universeCenter, nrPoints: nrPoints, coords: { coords, setCoords }, onLoad: onLoad, onAfterTransform: onTransform, onAfterReset: onReset, onClose: onClose }) })] })] }));
163
+ }, children: _jsx(Finish, { universeCenter: universeCenter, nrPoints: nrPoints, coords: { coords, setCoords }, trademarkCenter: { trademarkCenter, setTrademarkCenter }, onLoad: onLoad, onAfterTransform: onTransform, onAfterReset: onReset, onClose: onClose }) })] })] }));
161
164
  }
@@ -1,5 +1,5 @@
1
1
  import { JSX } from 'react';
2
- import { TAxisHook, TCatmullRomPointsHook, TCoordsHook, TImageHook, TRotationHook, TShow, TStatusHook } from './types';
2
+ import { TAxisHook, TCatmullRomPointsHook, TCoordsHook, TImageHook, TRotationHook, TShow, TStatusHook, TTrademarkHook } from './types';
3
3
  export declare function DrawCanvas(props: {
4
4
  machine: any;
5
5
  command: any;
@@ -10,6 +10,7 @@ export declare function DrawCanvas(props: {
10
10
  axis: TAxisHook;
11
11
  imageUrl?: string;
12
12
  coords: TCoordsHook;
13
+ trademarkCenter: TTrademarkHook;
13
14
  catmullRomPoints: TCatmullRomPointsHook;
14
15
  imageCoords: TImageHook;
15
16
  rotation: TRotationHook;
@@ -1 +1 @@
1
- {"version":3,"file":"DrawCanvas.d.ts","sourceRoot":"","sources":["../src/DrawCanvas.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAqD,MAAM,OAAO,CAAC;AAG/E,OAAO,EACL,SAAS,EACT,qBAAqB,EACrB,WAAW,EACX,UAAU,EACV,aAAa,EACb,KAAK,EACL,WAAW,EACZ,MAAM,SAAS,CAAC;AAIjB,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,OAAO,EAAE,GAAG,CAAC;IACb,OAAO,EAAE,GAAG,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,WAAW,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,GAAG,CAAC,OAAO,CA8gBd"}
1
+ {"version":3,"file":"DrawCanvas.d.ts","sourceRoot":"","sources":["../src/DrawCanvas.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAqD,MAAM,OAAO,CAAC;AAG/E,OAAO,EACL,SAAS,EACT,qBAAqB,EACrB,WAAW,EACX,UAAU,EACV,aAAa,EACb,KAAK,EACL,WAAW,EACX,cAAc,EACf,MAAM,SAAS,CAAC;AAKjB,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,OAAO,EAAE,GAAG,CAAC;IACb,OAAO,EAAE,GAAG,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,eAAe,EAAE,cAAc,CAAC;IAChC,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,WAAW,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,GAAG,CAAC,OAAO,CAisBd"}
@@ -4,31 +4,73 @@ import { Point } from './Point';
4
4
  import { SortedPoints } from './SortedPoints';
5
5
  import { ACTION, STATUS } from 'frame.statemachine';
6
6
  import { Polygon } from './Polygon';
7
+ import { round } from 'frame.akima';
7
8
  export function DrawCanvas(props) {
8
9
  const [mousePoint, setMousePoint] = useState(null);
10
+ const [mousePos, setMousePos] = useState({
11
+ x: 0,
12
+ y: 0,
13
+ });
9
14
  const [img, setImg] = useState(null);
15
+ const [trademarkImage, setTrademarkImage] = useState(null);
10
16
  const [zoom, setZoom] = useState(1.0);
11
17
  const [isDragging, setIsDragging] = useState(false);
12
18
  const [dragStart, setDragStart] = useState(null);
13
19
  const universeCenter = useMemo(() => new Point(props.width / 2, props.height / 2), [props.height, props.width]); // Center of the canvas is [400,300]
14
20
  const canvasRef = useRef(null);
21
+ // Memoize the trademark polygon so it's only created when coords change
22
+ const tradeMarkPolygon = useMemo(() => {
23
+ if (props.machine.name === STATUS.FORM_SCALED) {
24
+ return props.coords.coords.scale(0.9, 0.9);
25
+ }
26
+ return null;
27
+ }, [props.machine.name, props.coords.coords]);
28
+ const fromAngle = useMemo(() => (4 * Math.PI) / 6, []);
29
+ const toAngle = useMemo(() => (8 * Math.PI) / 6, []);
30
+ const drawTrade = useCallback((context, point) => {
31
+ const color = 'blue';
32
+ const oX = 10;
33
+ const oY = 10;
34
+ const p0 = new Point(point.X - oX, point.Y + oY, universeCenter);
35
+ const p1 = new Point(point.X + oX, point.Y + oY, universeCenter);
36
+ const p2 = new Point(point.X + oX, point.Y - oY, universeCenter);
37
+ const p3 = new Point(point.X - oX, point.Y - oY, universeCenter);
38
+ p0.drawLine(context, p1, color);
39
+ p1.drawLine(context, p2, color);
40
+ p2.drawLine(context, p3, color);
41
+ p3.drawLine(context, p0, color);
42
+ }, [universeCenter]);
43
+ const printTrademark = useCallback((context) => {
44
+ if (props.trademarkCenter.trademarkCenter && trademarkImage) {
45
+ props.trademarkCenter.trademarkCenter.drawPic(context, trademarkImage);
46
+ }
47
+ }, [props.trademarkCenter, trademarkImage]);
15
48
  const drawObjects = useCallback((context) => {
49
+ // Move drawTrademark inside the useCallback
16
50
  const sortedPoints = new SortedPoints(props.coords.coords, universeCenter);
17
51
  if (props.show.center) {
18
52
  sortedPoints.drawCenter(context, 'green', 500);
53
+ context.fillStyle = 'black';
54
+ context.fillText(`center: [${Math.round(sortedPoints.Center.X)}, ${Math.round(sortedPoints.Center.Y)}]`, 10, 380);
19
55
  }
20
56
  if (props.show.box) {
21
57
  sortedPoints.drawBox(context);
22
58
  }
23
59
  if (props.show.scaledBox) {
60
+ let sl;
61
+ let sh;
24
62
  if (props.scaledSL || props.scaledSH) {
25
- const sl = props.scaledSL || 0;
26
- const sh = props.scaledSH || 0;
27
- const center = sortedPoints.Center;
28
- const p1 = new Point(center.X - sl / 2, -center.Y - sh / 2, universeCenter);
29
- const p2 = new Point(center.X + sl / 2, -center.Y + sh / 2, universeCenter);
30
- Point.drawBox(context, p1, p2, 'black');
63
+ sl = props.scaledSL || 0;
64
+ sh = props.scaledSH || 0;
31
65
  }
66
+ else {
67
+ sl = sortedPoints.getExtension().xExt;
68
+ sh = sortedPoints.getExtension().yExt;
69
+ }
70
+ const center = sortedPoints.Center;
71
+ const p1 = new Point(center.X - sl / 2, -center.Y - sh / 2, universeCenter);
72
+ const p2 = new Point(center.X + sl / 2, -center.Y + sh / 2, universeCenter);
73
+ Point.drawBox(context, p1, p2, 'black');
32
74
  }
33
75
  if (props.show.polygon) {
34
76
  const polygon = new Polygon(props.coords.coords.Points, universeCenter);
@@ -70,6 +112,64 @@ export function DrawCanvas(props) {
70
112
  if (props.show.catmullRom) {
71
113
  sortedPoints.drawCatmullRom(context);
72
114
  }
115
+ if (props.machine.name === STATUS.FORM_SCALED) {
116
+ const origin = props.coords.coords.UniverseCenter;
117
+ // const trademarkPolygon = props.coords.coords.scale(0.9, 0.9);
118
+ // const trademarkPolygon = props.coords.coords.scaleByRadius(0.9);
119
+ // setTradeMarkLine(trademarkPolygon);
120
+ if (tradeMarkPolygon) {
121
+ const index = tradeMarkPolygon.findMinDistancePoint(new Point(mousePos.x, mousePos.y, universeCenter));
122
+ const fromIndex = tradeMarkPolygon.findIndexWithAngle(fromAngle);
123
+ const toIndex = tradeMarkPolygon.findIndexWithAngle(toAngle);
124
+ if (index >= fromIndex && index <= toIndex) {
125
+ const point = tradeMarkPolygon.Points[index];
126
+ const p1 = tradeMarkPolygon.Points[index - 1];
127
+ const p2 = tradeMarkPolygon.Points[index + 1];
128
+ const xDiff = p2.X - p1.X;
129
+ const yDiff = p2.Y - p1.Y;
130
+ let upperSide = true;
131
+ let rightSide = true;
132
+ if (xDiff < 0) {
133
+ if (yDiff < 0) {
134
+ upperSide = false;
135
+ console.log(`lower left(${upperSide}, ${rightSide})`);
136
+ }
137
+ else {
138
+ console.log(`upper left(${upperSide}, ${rightSide})`);
139
+ }
140
+ }
141
+ else {
142
+ rightSide = false;
143
+ if (yDiff < 0) {
144
+ upperSide = false;
145
+ console.log(`lower right(${upperSide}, ${rightSide})`);
146
+ }
147
+ else {
148
+ console.log(`upper right(${upperSide}, ${rightSide})`);
149
+ }
150
+ }
151
+ if (point) {
152
+ // setTrademarkCenter(point);
153
+ drawTrade(context, point);
154
+ }
155
+ }
156
+ }
157
+ }
158
+ else {
159
+ const index = props.coords.coords.findMinDistancePoint(new Point(mousePos.x, mousePos.y, universeCenter));
160
+ const point = props.coords.coords.Points[index];
161
+ if (point) {
162
+ point.draw(context, 'red', { text: 'closest', offset: 10 });
163
+ context.font = '16px Arial';
164
+ context.fillStyle = 'black';
165
+ context.fillText(`point ${index}: [${Math.round(point.X)}, ${Math.round(point.Y)}] mouse[${mousePos.x}, ${mousePos.y}]`, 10, 20);
166
+ }
167
+ }
168
+ // Draw trademark line if it exists
169
+ if (tradeMarkPolygon) {
170
+ tradeMarkPolygon.drawSegment(context, 'red', fromAngle, toAngle);
171
+ }
172
+ printTrademark(context);
73
173
  }, [
74
174
  props.coords.coords,
75
175
  props.show.center,
@@ -80,15 +180,27 @@ export function DrawCanvas(props) {
80
180
  props.show.catmullRomPoints,
81
181
  props.show.points,
82
182
  props.show.catmullRom,
183
+ props.machine.name,
83
184
  props.scaledSL,
84
185
  props.scaledSH,
85
186
  props.catmullRomPoints.catmullRomPoints,
86
- props.machine.name,
87
187
  props.axis.axis.x1,
88
188
  props.axis.axis.x2,
89
189
  universeCenter,
190
+ tradeMarkPolygon,
191
+ printTrademark,
90
192
  mousePoint,
193
+ mousePos.x,
194
+ mousePos.y,
195
+ fromAngle,
196
+ toAngle,
197
+ drawTrade,
91
198
  ]);
199
+ const loadTrademarkImage = useCallback((onLoad) => {
200
+ const newImg = new window.Image();
201
+ newImg.onload = () => onLoad(newImg);
202
+ newImg.src = '/public/R-Logo-schwarzaufweissq.gif';
203
+ }, []);
92
204
  // Split drawImageBackground into two functions: loadImage and drawImageBackground
93
205
  const loadImage = useCallback((src, onLoad) => {
94
206
  const newImg = new window.Image();
@@ -97,12 +209,7 @@ export function DrawCanvas(props) {
97
209
  }, []);
98
210
  // Split drawImageBackground into two functions: loadImage and drawImageBackground
99
211
  const drawImageBackground = useCallback((context, canvas) => {
100
- if (props.imageUrl && props.show.background) {
101
- if (!img) {
102
- setImg(null); // Reset img to null before loading a new image
103
- loadImage(props.imageUrl, setImg);
104
- return true;
105
- }
212
+ if (props.imageUrl && props.show.background && img) {
106
213
  context.clearRect(0, 0, canvas.width, canvas.height);
107
214
  context.save();
108
215
  let rotationRequired = false;
@@ -154,7 +261,6 @@ export function DrawCanvas(props) {
154
261
  zoom,
155
262
  img,
156
263
  drawObjects,
157
- loadImage,
158
264
  universeCenter.X,
159
265
  universeCenter.Y,
160
266
  ]);
@@ -242,10 +348,24 @@ export function DrawCanvas(props) {
242
348
  case STATUS.POINTS_TRANSFORMED:
243
349
  console.log(`points are already transformed -> no point can be added`);
244
350
  break;
351
+ case STATUS.FORM_SCALED:
352
+ if (tradeMarkPolygon) {
353
+ const index = tradeMarkPolygon.findMinDistancePoint(point);
354
+ const fromIndex = tradeMarkPolygon.findIndexWithAngle(fromAngle);
355
+ const toIndex = tradeMarkPolygon.findIndexWithAngle(toAngle);
356
+ if (index >= fromIndex || index > toIndex) {
357
+ props.trademarkCenter.setTrademarkCenter(tradeMarkPolygon.Points[index]);
358
+ console.log(`trademark at [${point.X}, ${point.Y}] index: ${index} -> [${round(tradeMarkPolygon.Points[index].X)}, ${round(tradeMarkPolygon.Points[index].Y)}]`);
359
+ }
360
+ else {
361
+ console.log(`clicked point is outside trademark area`);
362
+ }
363
+ }
364
+ break;
245
365
  default:
246
366
  throw new Error(`Unknown machine state: ${props.machine.name}`);
247
367
  }
248
- }, [getCurrentPoint, props]);
368
+ }, [fromAngle, getCurrentPoint, props, toAngle, tradeMarkPolygon]);
249
369
  const handleContextMenu = useCallback((event) => {
250
370
  event.preventDefault();
251
371
  const canvas = canvasRef.current;
@@ -300,6 +420,7 @@ export function DrawCanvas(props) {
300
420
  if (!canvas)
301
421
  return;
302
422
  const point = getCurrentPoint(canvas, event);
423
+ setMousePos({ x: Math.round(point.X), y: Math.round(point.Y) });
303
424
  // Handle image dragging
304
425
  if (isDragging && dragStart) {
305
426
  const deltaX = event.clientX - dragStart.x;
@@ -360,6 +481,18 @@ export function DrawCanvas(props) {
360
481
  setIsDragging(false);
361
482
  setDragStart(null);
362
483
  }, []);
484
+ useEffect(() => {
485
+ const canvas = canvasRef.current;
486
+ if (canvas) {
487
+ const context = canvas.getContext('2d');
488
+ if (context) {
489
+ if (props.trademarkCenter.trademarkCenter) {
490
+ props.trademarkCenter.trademarkCenter.drawCross(context, 'purple', 100, 15);
491
+ }
492
+ }
493
+ }
494
+ }, [props.trademarkCenter]);
495
+ // Extra useEffect to handle rotation redraw
363
496
  useEffect(() => {
364
497
  if (img && props.rotation.rotationAngle !== 0) {
365
498
  const canvas = canvasRef.current;
@@ -423,9 +556,11 @@ export function DrawCanvas(props) {
423
556
  // Add this useEffect to reset img when imageUrl changes
424
557
  useEffect(() => {
425
558
  if (props.imageUrl) {
426
- setImg(null); // Clear the previous image
427
- loadImage(props.imageUrl, setImg); // Load the new image
559
+ loadImage(props.imageUrl, setImg); // Load the new image only once
428
560
  }
429
561
  }, [props.imageUrl, loadImage]);
562
+ useEffect(() => {
563
+ loadTrademarkImage(setTrademarkImage);
564
+ }, [loadTrademarkImage]);
430
565
  return (_jsx("canvas", { ref: canvasRef, width: props.width, height: props.height, id: "idCanvas", style: { backgroundColor: 'lightgrey' }, children: "Your browser does not support the HTML canvas tag." }));
431
566
  }
package/dist/Finish.d.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  import { Polygon } from './Polygon';
2
2
  import { Point } from './Point';
3
- import { TCoordsHook } from './types';
3
+ import { TCoordsHook, TTrademarkHook } from './types';
4
4
  export declare function Finish(props: {
5
5
  universeCenter: Point;
6
6
  nrPoints: number;
7
7
  coords: TCoordsHook;
8
+ trademarkCenter: TTrademarkHook;
8
9
  onLoad: (nrPoints: number) => void;
9
10
  onAfterTransform: () => void;
10
11
  onAfterReset: () => void;
11
- onClose: (pol: Polygon) => () => void;
12
+ onClose: (pol: Polygon, trademark?: Point) => () => void;
12
13
  }): import("react/jsx-runtime").JSX.Element;
13
14
  //# sourceMappingURL=Finish.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Finish.d.ts","sourceRoot":"","sources":["../src/Finish.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAC5B,cAAc,EAAE,KAAK,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;CACvC,2CA4HA"}
1
+ {"version":3,"file":"Finish.d.ts","sourceRoot":"","sources":["../src/Finish.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGtD,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAC5B,cAAc,EAAE,KAAK,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,eAAe,EAAE,cAAc,CAAC;IAChC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,KAAK,KAAK,MAAM,IAAI,CAAC;CAC1D,2CAyIA"}
package/dist/Finish.js CHANGED
@@ -3,6 +3,7 @@ import { Box, Button } from '@mui/material';
3
3
  import { useState } from 'react';
4
4
  import { Polygon } from './Polygon';
5
5
  import { Point } from './Point';
6
+ import { createEquidistantPoints } from 'frame.akima';
6
7
  export function Finish(props) {
7
8
  const [originalCoords, setOriginalCoords] = useState(undefined);
8
9
  const styleButton = {
@@ -34,16 +35,20 @@ export function Finish(props) {
34
35
  return { coords: transformed, dist };
35
36
  };
36
37
  const onTransform = () => {
37
- let distance = 1000;
38
- let coordinates = props.coords.coords.clone();
38
+ const coordinates = props.coords.coords.clone();
39
39
  setOriginalCoords(props.coords.coords);
40
- while (distance > 0.01) {
41
- // find the point with the minimum distance to the center
42
- const { dist, coords } = refine(coordinates);
43
- distance = dist;
44
- coordinates = coords;
45
- }
46
- props.coords.setCoords(coordinates);
40
+ // Convert your Points to AkimaPoints
41
+ const akimaPoints = coordinates.Points.map((point) => ({
42
+ X: point.X,
43
+ Y: point.Y,
44
+ }));
45
+ const { points, center } = createEquidistantPoints(akimaPoints, 128);
46
+ console.log(`center during transform: [${center.X}, ${center.Y}]`);
47
+ // Create a new Polygon from the equidistant Akima points
48
+ const newCoordinates = new Polygon(points.map((p) => {
49
+ return new Point(p.X + center.X, p.Y + center.Y, props.universeCenter);
50
+ }), props.universeCenter);
51
+ props.coords.setCoords(newCoordinates);
47
52
  props.onAfterTransform();
48
53
  };
49
54
  const onReset = () => {
@@ -53,7 +58,7 @@ export function Finish(props) {
53
58
  props.onAfterReset();
54
59
  }
55
60
  };
56
- return (_jsxs(Box, { id: "id.Finish", sx: styleButton, children: [_jsx(Button, { variant: "contained", disabled: props.coords.coords.Length < 3, onClick: originalCoords === undefined ? onTransform : onReset, sx: { width: '200px' }, children: originalCoords === undefined ? 'Start Transformation' : 'Undo' }), _jsx(Button, { variant: "contained", disabled: originalCoords === undefined, onClick: props.onClose(props.coords.coords), children: "Create RT1" }), _jsx(Button, { variant: "contained", onClick: () => {
61
+ return (_jsxs(Box, { id: "id.Finish", sx: styleButton, children: [_jsx(Button, { variant: "contained", disabled: props.coords.coords.Length < 3, onClick: originalCoords === undefined ? onTransform : onReset, sx: { width: '200px' }, children: originalCoords === undefined ? 'Start Transformation' : 'Undo' }), _jsx(Button, { "data-testid": "id.button.CreateRT1", variant: "contained", disabled: originalCoords === undefined, onClick: props.onClose(props.coords.coords, props.trademarkCenter.trademarkCenter), children: "Create RT1" }), _jsx(Button, { variant: "contained", onClick: () => {
57
62
  props.coords.coords.save('frame.image.json');
58
63
  }, children: "Save Points" }), _jsxs(Button, { variant: "contained", component: "label", children: ["Load Points", _jsx("input", { type: "file", accept: "application/json", hidden: true, onChange: async (e) => {
59
64
  const file = e.target.files?.[0];
@@ -3,8 +3,8 @@ import { Box, Modal } from '@mui/material';
3
3
  import { Designer } from './Designer';
4
4
  export function ModalDesigner(props) {
5
5
  return (_jsx(Modal, { open: props.isOpen, onClose: props.onClose, "aria-labelledby": "modal-title", "aria-describedby": "modal-description", children: _jsx(Box, { id: "id.box.ModalDesigner", sx: {
6
- width: 1000,
7
- height: 700,
6
+ width: 1400,
7
+ height: 900,
8
8
  bgcolor: 'background.paper',
9
9
  boxShadow: 24,
10
10
  p: 4,
package/dist/Point.d.ts CHANGED
@@ -21,6 +21,7 @@ export declare class Point {
21
21
  offset: number;
22
22
  }, radius?: number): void;
23
23
  drawCross(context: CanvasRenderingContext2D, color?: string, offset?: number, lineWidth?: number): void;
24
+ drawPic(context: CanvasRenderingContext2D, img: HTMLImageElement): void;
24
25
  drawLine(context: CanvasRenderingContext2D, point: Point, color?: string, lineWidth?: number): void;
25
26
  rounded(digits?: number): Point;
26
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Point.d.ts","sourceRoot":"","sources":["../src/Point.ts"],"names":[],"mappings":"AAAA,qBAAa,KAAK;IAChB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;IAExB,MAAM,CAAC,OAAO,CACZ,OAAO,EAAE,wBAAwB,EACjC,EAAE,EAAE,KAAK,EACT,EAAE,EAAE,KAAK,EACT,KAAK,EAAE,MAAM;IAaf,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,KAAK;gBAM/B,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK;IAOhD,KAAK,IAAI,KAAK;IAId,MAAM,IAAI;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAOlC,IAAI,CAAC,WAEJ;IAED,IAAI,CAAC,WAEJ;IAED,IAAI,MAAM,IAAI,KAAK,CAElB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM;IAW/B,IAAI,CACF,OAAO,EAAE,wBAAwB,EACjC,WAAW,CAAC,EAAE,MAAM,EACpB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,EACD,MAAM,SAAI,GACT,IAAI;IAsBP,SAAS,CACP,OAAO,EAAE,wBAAwB,EACjC,KAAK,SAAU,EACf,MAAM,SAAK,EACX,SAAS,SAAI,GACZ,IAAI;IAiBP,QAAQ,CACN,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,KAAK,EACZ,KAAK,SAAU,EACf,SAAS,SAAI,GACZ,IAAI;IASP,OAAO,CAAC,MAAM,SAAI,GAAG,KAAK;CAQ3B"}
1
+ {"version":3,"file":"Point.d.ts","sourceRoot":"","sources":["../src/Point.ts"],"names":[],"mappings":"AAAA,qBAAa,KAAK;IAChB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;IAExB,MAAM,CAAC,OAAO,CACZ,OAAO,EAAE,wBAAwB,EACjC,EAAE,EAAE,KAAK,EACT,EAAE,EAAE,KAAK,EACT,KAAK,EAAE,MAAM;IAaf,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,KAAK;gBAM/B,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK;IAOhD,KAAK,IAAI,KAAK;IAId,MAAM,IAAI;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAOlC,IAAI,CAAC,WAEJ;IAED,IAAI,CAAC,WAEJ;IAED,IAAI,MAAM,IAAI,KAAK,CAElB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM;IAW/B,IAAI,CACF,OAAO,EAAE,wBAAwB,EACjC,WAAW,CAAC,EAAE,MAAM,EACpB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,EACD,MAAM,SAAI,GACT,IAAI;IAsBP,SAAS,CACP,OAAO,EAAE,wBAAwB,EACjC,KAAK,SAAU,EACf,MAAM,SAAK,EACX,SAAS,SAAI,GACZ,IAAI;IAiBP,OAAO,CAAC,OAAO,EAAE,wBAAwB,EAAE,GAAG,EAAE,gBAAgB,GAAG,IAAI;IAYvE,QAAQ,CACN,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,KAAK,EACZ,KAAK,SAAU,EACf,SAAS,SAAI,GACZ,IAAI;IASP,OAAO,CAAC,MAAM,SAAI,GAAG,KAAK;CAQ3B"}
package/dist/Point.js CHANGED
@@ -69,6 +69,11 @@ export class Point {
69
69
  const point2 = new Point(this.X, this.Y - offset, this.Origin);
70
70
  point2.drawLine(context, new Point(this.X, this.Y + offset, this.Origin), color, lineWidth);
71
71
  }
72
+ drawPic(context, img) {
73
+ const width = 16;
74
+ const height = 16;
75
+ context.drawImage(img, this.X + this.xOrigin - width / 2, this.yOrigin - this.Y - height / 2, width, height);
76
+ }
72
77
  drawLine(context, point, color = 'black', lineWidth = 1) {
73
78
  context.strokeStyle = color;
74
79
  context.lineWidth = lineWidth;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Point } from './Point';
3
3
  declare const PointsForm: React.FC<{
4
+ origin: Point;
4
5
  title: string;
5
6
  onCloseCancel: () => void;
6
7
  onCloseContinue: (points: Point[], universeCenter: Point) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"PointsForm.d.ts","sourceRoot":"","sources":["../src/PointsForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,eAAe,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,cAAc,EAAE,KAAK,KAAK,IAAI,CAAC;CACnE,CAyFA,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"PointsForm.d.ts","sourceRoot":"","sources":["../src/PointsForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC;IACzB,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,eAAe,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,cAAc,EAAE,KAAK,KAAK,IAAI,CAAC;CACnE,CA2FA,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -1,9 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useCallback, useMemo, useState } from 'react';
2
+ import { useCallback, useState } from 'react';
3
3
  import { Point } from './Point';
4
4
  const PointsForm = (props) => {
5
5
  const [text, setText] = useState('');
6
- const origin = useMemo(() => new Point(400, 250), []);
7
6
  const handleChange = useCallback((e) => {
8
7
  setText(e.target.value);
9
8
  }, []);
@@ -39,26 +38,26 @@ const PointsForm = (props) => {
39
38
  if (y > yMax) {
40
39
  yMax = y;
41
40
  }
42
- const p = new Point(x, y, origin);
41
+ const p = new Point(x, y, props.origin);
43
42
  coords.push(p);
44
43
  }
45
- props.onCloseContinue(coords, origin);
46
- }, [origin, props, text]);
47
- return (_jsxs("form", { onSubmit: handleSubmit, children: [_jsx("label", { htmlFor: "textInput", children: "Enter Text:" }), _jsx("input", { id: "textInput", type: "text", value: text, onChange: handleChange, placeholder: "Type here..." }), _jsx("button", { onClick: props.onCloseCancel, style: {
48
- padding: '8px 16px',
49
- border: '1px solid #ddd',
50
- borderRadius: '4px',
51
- background: 'white',
52
- cursor: 'pointer',
53
- fontSize: '14px',
54
- }, children: "Cancel" }), ' ', _jsx("button", { type: "submit", style: {
55
- padding: '8px 16px',
56
- border: 'none',
57
- borderRadius: '4px',
58
- background: '#007bff',
59
- color: 'white',
60
- cursor: 'pointer',
61
- fontSize: '14px',
62
- }, children: props.title })] }));
44
+ props.onCloseContinue(coords, props.origin);
45
+ }, [props, text]);
46
+ return (_jsxs("div", { "data-testid": "id.PointsForm", children: [_jsx("h2", { children: props.title }), _jsxs("form", { onSubmit: handleSubmit, children: [_jsx("label", { htmlFor: "textInput", children: "Enter Text:" }), _jsx("input", { id: "textInput", type: "text", value: text, onChange: handleChange, placeholder: "Type here..." }), _jsx("button", { onClick: props.onCloseCancel, style: {
47
+ padding: '8px 16px',
48
+ border: '1px solid #ddd',
49
+ borderRadius: '4px',
50
+ background: 'white',
51
+ cursor: 'pointer',
52
+ fontSize: '14px',
53
+ }, children: "Cancel" }), ' ', _jsx("button", { type: "submit", style: {
54
+ padding: '8px 16px',
55
+ border: 'none',
56
+ borderRadius: '4px',
57
+ background: '#007bff',
58
+ color: 'white',
59
+ cursor: 'pointer',
60
+ fontSize: '14px',
61
+ }, children: "Import" })] })] }));
63
62
  };
64
63
  export default PointsForm;
package/dist/Polygon.d.ts CHANGED
@@ -11,6 +11,7 @@ export declare class Polygon {
11
11
  universeCenter: Point;
12
12
  }): Polygon;
13
13
  constructor(points: Point[], universeCenter: Point);
14
+ get UniverseCenter(): Point;
14
15
  clone(): Polygon;
15
16
  toJSON(): {
16
17
  points: {
@@ -48,6 +49,8 @@ export declare class Polygon {
48
49
  createNidek(): string;
49
50
  assertEquiDistantAngles(): void;
50
51
  drawPoints(context: CanvasRenderingContext2D, linesFromOrigin: boolean, color?: string): void;
52
+ findIndexWithAngle(angle: number): number;
53
+ drawSegment(context: CanvasRenderingContext2D, color?: string, fromAngle?: number, toAngle?: number): void;
51
54
  drawPolygon(context: CanvasRenderingContext2D, color?: string, transparency?: number): void;
52
55
  drawCenter(context: CanvasRenderingContext2D, color?: string): void;
53
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Polygon.d.ts","sourceRoot":"","sources":["../src/Polygon.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;IAErB,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAAC,cAAc,EAAE,KAAK,CAAA;KAAE,GAAG,OAAO;gBAQ9D,MAAM,EAAE,KAAK,EAAE,EAAE,cAAc,EAAE,KAAK;IASlD,KAAK,IAAI,OAAO;IAKhB,MAAM,IAAI;QACR,MAAM,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACnC,cAAc,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC1C;IAOD,IAAI,CAAC,IAAI,EAAE,MAAM;IAajB,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,MAAM,IAAI,KAAK,EAAE,CAEpB;IAED,IAAI,QAAQ;;;QAIX;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,MAAM,IAAI,KAAK,CAOlB;IAED,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK;IAOxB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAOtC,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAK3B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAK7B,oBAAoB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;IAY1C,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,GAAG,OAAO;IAQ/D,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAU7C,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,OAAO;IAyBjE,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;IAYtC,SAAS,IAAI,MAAM;IAWnB,SAAS,IAAI,MAAM;IAOnB,WAAW,IAAI,MAAM;IASrB,uBAAuB,IAAI,IAAI;IAwB/B,UAAU,CACR,OAAO,EAAE,wBAAwB,EACjC,eAAe,EAAE,OAAO,EACxB,KAAK,SAAW,GACf,IAAI;IAsBP,WAAW,CACT,OAAO,EAAE,wBAAwB,EACjC,KAAK,SAAQ,EACb,YAAY,SAAM,GACjB,IAAI;IAuBP,UAAU,CAAC,OAAO,EAAE,wBAAwB,EAAE,KAAK,SAAU,GAAG,IAAI;CAMrE"}
1
+ {"version":3,"file":"Polygon.d.ts","sourceRoot":"","sources":["../src/Polygon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAIhC,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;IAErB,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAAC,cAAc,EAAE,KAAK,CAAA;KAAE,GAAG,OAAO;gBAQ9D,MAAM,EAAE,KAAK,EAAE,EAAE,cAAc,EAAE,KAAK;IASlD,IAAI,cAAc,IAAI,KAAK,CAE1B;IAED,KAAK,IAAI,OAAO;IAKhB,MAAM,IAAI;QACR,MAAM,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACnC,cAAc,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC1C;IAOD,IAAI,CAAC,IAAI,EAAE,MAAM;IAajB,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,MAAM,IAAI,KAAK,EAAE,CAEpB;IAED,IAAI,QAAQ;;;QAIX;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,MAAM,IAAI,KAAK,CAOlB;IAED,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK;IAOxB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAOtC,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAK3B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAK7B,oBAAoB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;IAY1C,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,GAAG,OAAO;IAQ/D,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAU7C,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,OAAO;IAsBjE,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;IAYtC,SAAS,IAAI,MAAM;IAiCnB,SAAS,IAAI,MAAM;IAOnB,WAAW,IAAI,MAAM;IASrB,uBAAuB,IAAI,IAAI;IAwB/B,UAAU,CACR,OAAO,EAAE,wBAAwB,EACjC,eAAe,EAAE,OAAO,EACxB,KAAK,SAAW,GACf,IAAI;IAsBP,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAWzC,WAAW,CACT,OAAO,EAAE,wBAAwB,EACjC,KAAK,SAAQ,EACb,SAAS,SAAI,EACb,OAAO,SAAc,GACpB,IAAI;IAoBP,WAAW,CACT,OAAO,EAAE,wBAAwB,EACjC,KAAK,SAAQ,EACb,YAAY,SAAM,GACjB,IAAI;IAuBP,UAAU,CAAC,OAAO,EAAE,wBAAwB,EAAE,KAAK,SAAU,GAAG,IAAI;CAMrE"}
package/dist/Polygon.js CHANGED
@@ -1,6 +1,6 @@
1
- import { createPolarCatmullRom } from 'frame.akima';
2
1
  import { Point } from './Point';
3
2
  import { Nidek } from 'frame.nidek';
3
+ import { createEquidistantPoints } from 'frame.akima';
4
4
  export class Polygon {
5
5
  points;
6
6
  universeCenter;
@@ -21,6 +21,9 @@ export class Polygon {
21
21
  this.yMax = Math.max(...points.map((point) => point.Y));
22
22
  this.universeCenter = universeCenter;
23
23
  }
24
+ get UniverseCenter() {
25
+ return this.universeCenter;
26
+ }
24
27
  clone() {
25
28
  const clonedPoints = this.points.map((point) => point.clone());
26
29
  return new Polygon(clonedPoints, this.universeCenter);
@@ -118,19 +121,19 @@ export class Polygon {
118
121
  }
119
122
  createCatmullRomPoints(nrPoints, origin) {
120
123
  const points = this.points.map((xPoint) => {
121
- return {
122
- x: xPoint.X - (origin ? origin.X : 0),
123
- y: xPoint.Y - (origin ? origin.Y : 0),
124
- };
124
+ return new Point(xPoint.X, xPoint.Y);
125
125
  });
126
- const catmullRomFunc = createPolarCatmullRom(points);
127
- const catmullRomPoints = [];
128
- for (let iloop = 0; iloop < nrPoints; iloop += 1) {
129
- const angle = (iloop * Math.PI * 2) / nrPoints;
130
- const { x, y } = catmullRomFunc(angle);
131
- catmullRomPoints.push(new Point(x + (origin ? origin.X : 0), y + (origin ? origin.Y : 0), this.universeCenter));
126
+ let catmullPolygon;
127
+ if (points.length < 4) {
128
+ catmullPolygon = new Polygon(points, this.universeCenter);
129
+ }
130
+ else {
131
+ const { points: newPoints, center } = createEquidistantPoints(points, nrPoints);
132
+ const akimaPoints = newPoints.map((p) => {
133
+ return new Point(p.X + center.X, p.Y + center.Y, this.universeCenter);
134
+ });
135
+ catmullPolygon = new Polygon(akimaPoints, this.universeCenter);
132
136
  }
133
- const catmullPolygon = new Polygon(catmullRomPoints, this.universeCenter);
134
137
  return catmullPolygon;
135
138
  }
136
139
  findNearestPoint(point) {
@@ -142,9 +145,22 @@ export class Polygon {
142
145
  return nearestIndex;
143
146
  }
144
147
  createRT1() {
148
+ if (this.points.length !== 128) {
149
+ throw new Error('RT1 can only be created for 128 points polygon.');
150
+ }
145
151
  let rt1 = '';
152
+ const singleAngle = (Math.PI * 2) / 128;
146
153
  for (let iloop = 0; iloop < this.points.length; iloop += 1) {
147
154
  const originalPoint = this.points[iloop];
155
+ const angle = originalPoint.relAtan(new Point(0, 0));
156
+ const delta = Math.abs(angle - singleAngle * iloop);
157
+ console.log(`point[${iloop}] = [${originalPoint.X}, ${originalPoint.Y}], angle: ${angle}, expected: ${singleAngle * iloop}, delta: ${delta}`);
158
+ if (delta > 1e-5) {
159
+ throw new Error(`Points are not equidistant in angle at index ${iloop} (delta: ${delta}, deviation: ${Math.abs(delta - (Math.PI * 2) / 128)}`);
160
+ }
161
+ if (iloop === 0 || iloop === this.points.length / 2) {
162
+ console.log(`point ${iloop} x: ${originalPoint.X}`);
163
+ }
148
164
  rt1 += Math.round(originalPoint.Radius * 10)
149
165
  .toString()
150
166
  .padStart(4, '0');
@@ -197,6 +213,30 @@ export class Polygon {
197
213
  }
198
214
  });
199
215
  }
216
+ findIndexWithAngle(angle) {
217
+ const index = this.points.findIndex((xPoint) => {
218
+ const ptAngle = xPoint.relAtan(new Point(0, 0));
219
+ return ptAngle >= angle;
220
+ });
221
+ if (index === -1) {
222
+ return this.points.length - 1;
223
+ }
224
+ return index;
225
+ }
226
+ drawSegment(context, color = 'red', fromAngle = 0, toAngle = Math.PI * 2) {
227
+ if (this.points.length < 2)
228
+ return;
229
+ context.strokeStyle = color;
230
+ context.lineWidth = 2;
231
+ context.beginPath();
232
+ const fromIndex = this.findIndexWithAngle(fromAngle);
233
+ const toIndex = this.findIndexWithAngle(toAngle);
234
+ context.moveTo(this.universeCenter.X + this.points[fromIndex].X, this.universeCenter.Y - this.points[fromIndex].Y);
235
+ for (let i = fromIndex + 1; i <= toIndex; i++) {
236
+ context.lineTo(this.universeCenter.X + this.points[i].X, this.universeCenter.Y - this.points[i].Y);
237
+ }
238
+ context.stroke();
239
+ }
200
240
  drawPolygon(context, color = 'red', transparency = 0.4) {
201
241
  if (this.points.length < 2)
202
242
  return;
@@ -1,11 +1,11 @@
1
- import { TCoordsHook } from './types';
1
+ import { TCoordsHook, TNumberHook } from './types';
2
2
  export declare function ScaleForm(props: {
3
3
  title: string;
4
4
  coords: TCoordsHook;
5
5
  currentPoints: number;
6
6
  disabled: boolean;
7
- sl?: number;
8
- sh?: number;
7
+ scaledSL: TNumberHook;
8
+ scaledSH: TNumberHook;
9
9
  onCloseCancel: () => void;
10
10
  onCloseContinue: (length: number, height: number) => void;
11
11
  }): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"ScaleForm.d.ts","sourceRoot":"","sources":["../src/ScaleForm.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3D,2CAwMA"}
1
+ {"version":3,"file":"ScaleForm.d.ts","sourceRoot":"","sources":["../src/ScaleForm.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAInD,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,WAAW,CAAC;IACtB,QAAQ,EAAE,WAAW,CAAC;IACtB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3D,2CAuNA"}
package/dist/ScaleForm.js CHANGED
@@ -2,16 +2,18 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from 'react';
3
3
  import { ScaleInput } from './ScaleInput';
4
4
  import { Point } from './Point';
5
+ import { createEquidistantPoints } from 'frame.akima';
6
+ import { Polygon } from './Polygon';
5
7
  export function ScaleForm(props) {
6
8
  const scalingParam = 10;
7
9
  if (typeof props.currentPoints !== 'number' &&
8
10
  typeof props.currentPoints !== 'string') {
9
11
  console.error('Invalid currentPoints in ScaleForm:', props.currentPoints);
10
12
  }
11
- const [drawnLength, setDrawnLength] = useState(props.sl ?? 0);
12
- const [inputLength, setInputLength] = useState(props.sl ?? 0);
13
- const [length, setLength] = useState(props.sl ?? 0);
14
- const [height, setHeight] = useState(props.sh ?? 0);
13
+ const [drawnLength, setDrawnLength] = useState(props.scaledSL.value ?? 0);
14
+ const [inputLength, setInputLength] = useState(props.scaledSL.value ?? 0);
15
+ const [length, setLength] = useState(props.scaledSL.value);
16
+ const [height, setHeight] = useState(props.scaledSH.value);
15
17
  const [ratio, setRatio] = useState(1);
16
18
  function onChangeLength(e) {
17
19
  const newLength = Math.round(parseFloat(e.target.value) * scalingParam) / scalingParam;
@@ -26,31 +28,28 @@ export function ScaleForm(props) {
26
28
  scalingParam;
27
29
  setInputLength(newLength);
28
30
  setHeight(newHeight);
31
+ props.scaledSL.setValue(newLength);
32
+ props.scaledSH.setValue(newHeight);
29
33
  }
30
34
  function onChangeHeight(e) {
31
35
  const newHeight = Math.round(parseFloat(e.target.value) * scalingParam) / scalingParam;
32
- const newLength = Math.round(newHeight * ratioLength2Height * scalingParam) / scalingParam;
33
- setInputLength(newLength);
36
+ // setInputLength(newLength);
34
37
  setHeight(newHeight);
38
+ props.scaledSH.setValue(newHeight);
35
39
  }
36
40
  const handleSubmit = (e) => {
37
41
  e.preventDefault();
38
- const scaledPoints = [];
39
- const scaledPolygon = props.coords.coords.clone();
40
- for (let loop = 0; loop < scaledPolygon.Points.length; loop += 1) {
41
- const point = scaledPolygon.Points[loop];
42
- const angle = point.relAtan(new Point(0, 0));
43
- // Step 2: Scale the radius
44
- const scaledRadius = point.Radius * ratio;
45
- // Step 3: Convert back to Cartesian coordinates
46
- const scaledX = scaledRadius * Math.cos(angle);
47
- const scaledY = scaledRadius * Math.sin(angle);
48
- const scaledP = new Point(scaledX, scaledY, point.Origin);
49
- scaledPoints.push(scaledP);
50
- scaledPolygon.set(loop, scaledP);
51
- }
52
- props.coords.setCoords(scaledPolygon);
53
- props.onCloseContinue(drawnLength, height);
42
+ const ratioX = (length ?? 0) / (xMax - xMin);
43
+ const ratioY = (height ?? 0) / (yMax - yMin);
44
+ const ratio = Math.min(ratioX, ratioY);
45
+ console.log(`xMin: ${xMin}, xMax: ${xMax}, yMin: ${yMin}, yMax: ${yMax}`);
46
+ console.log(`length: ${length}, height: ${height}, ratio: ${ratio}`);
47
+ console.log(`scaling ratio: ${ratio}, ratioX: ${ratioX}, ratioY: ${ratioY}`);
48
+ const scaledPolygon = props.coords.coords.scale(ratioX, ratioY);
49
+ const { points } = createEquidistantPoints(scaledPolygon.Points, scaledPolygon.Points.length);
50
+ const equidistantPolygon = new Polygon(points.map((pt) => new Point(pt.X, pt.Y, props.coords.coords.UniverseCenter)), props.coords.coords.UniverseCenter);
51
+ props.coords.setCoords(equidistantPolygon);
52
+ props.onCloseContinue(drawnLength, height ?? 0);
54
53
  };
55
54
  let xMin = 0;
56
55
  let xMax = 0;
@@ -1,11 +1,11 @@
1
- import { TNumberValue } from './types';
1
+ import { TNumberHook } from './types';
2
2
  export declare function ScaleInput(props: {
3
3
  title: string;
4
4
  disabled?: boolean;
5
5
  extension: number;
6
6
  ratio: number;
7
7
  scalingParam: number;
8
- value: TNumberValue;
8
+ value: TNumberHook;
9
9
  setValue: (e: React.ChangeEvent<HTMLInputElement>) => void;
10
10
  }): import("react/jsx-runtime").JSX.Element;
11
11
  //# sourceMappingURL=ScaleInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ScaleInput.d.ts","sourceRoot":"","sources":["../src/ScaleInput.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;CAC5D,2CA0DA"}
1
+ {"version":3,"file":"ScaleInput.d.ts","sourceRoot":"","sources":["../src/ScaleInput.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;CAC5D,2CA8CA"}
@@ -1,15 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useState } from 'react';
3
2
  export function ScaleInput(props) {
4
3
  const id = `scale-${props.title.toLowerCase()}`;
5
- const [value, setValue] = useState(props.value.value ?? 0);
6
- function onChangeValue(e) {
7
- const parsed = parseFloat(e.target.value);
8
- setValue(parsed);
9
- }
10
- useEffect(() => {
11
- setValue(props.value.value ?? 0);
12
- }, [props.value]);
13
4
  // useEffect(() => {
14
5
  // console.log(`extension has changed to ${props.extension}`);
15
6
  // props.value.setValue(props.extension);
@@ -21,7 +12,7 @@ export function ScaleInput(props) {
21
12
  marginBottom: '8px',
22
13
  fontWeight: 500,
23
14
  fontSize: '14px',
24
- }, children: props.title }), _jsx("input", { id: id, type: "number", value: props.value.value, onChange: props.setValue, step: 1 / props.scalingParam, min: 1 / props.scalingParam, max: "1000", style: {
15
+ }, children: props.title }), _jsx("input", { id: id, type: "number", value: props.value.value ?? 0, onChange: props.setValue, step: 1 / props.scalingParam, min: 1 / props.scalingParam, max: "1000", style: {
25
16
  width: '100%',
26
17
  maxWidth: '100px',
27
18
  padding: '8px 12px',
@@ -29,5 +20,5 @@ export function ScaleInput(props) {
29
20
  borderRadius: '4px',
30
21
  fontSize: '14px',
31
22
  boxSizing: 'border-box',
32
- }, placeholder: `Enter scale ${props.title.toLowerCase()} (e.g., 1.5)`, autoFocus: true, disabled: props.disabled ?? false })] }));
23
+ }, placeholder: `Enter scale ${props.title.toLowerCase()} (e.g., 1.5)`, disabled: props.disabled ?? false })] }));
33
24
  }
@@ -42,6 +42,10 @@ export declare class SortedPoints {
42
42
  get RadiusKoeffs(): number[];
43
43
  drawPoints(context: CanvasRenderingContext2D, color?: string, offset?: number, radius?: number, each?: number): void;
44
44
  drawCenter(context: CanvasRenderingContext2D, color?: string, extension?: number, lineWidth?: number): void;
45
+ getExtension(): {
46
+ xExt: number;
47
+ yExt: number;
48
+ };
45
49
  drawBox(context: CanvasRenderingContext2D, color?: string): void;
46
50
  drawCatmullRom(context: CanvasRenderingContext2D): void;
47
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SortedPoints.d.ts","sourceRoot":"","sources":["../src/SortedPoints.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,cAAc,CAAQ;gBAElB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,UAAO;IA6BhE;;;;;;;OAOG;IACH,IAAI,MAAM,UAgBT;IAED,IAAI,OAAO,IAAI,MAAM,CAGpB;IAED,IAAI,YAAY,IAAI,MAAM,EAAE,CAI3B;IAED,IAAI,YAAY,IAAI,MAAM,EAAE,CAI3B;IAED,UAAU,CACR,OAAO,EAAE,wBAAwB,EACjC,KAAK,SAAU,EACf,MAAM,SAAK,EACX,MAAM,SAAI,EACV,IAAI,SAAI,GACP,IAAI;IAiBP,UAAU,CACR,OAAO,EAAE,wBAAwB,EACjC,KAAK,SAAU,EACf,SAAS,SAAK,EACd,SAAS,SAAI,GACZ,IAAI;IAmCP,OAAO,CAAC,OAAO,EAAE,wBAAwB,EAAE,KAAK,SAAS,GAAG,IAAI;IAsChE,cAAc,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI;CAMxD"}
1
+ {"version":3,"file":"SortedPoints.d.ts","sourceRoot":"","sources":["../src/SortedPoints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,cAAc,CAAQ;gBAElB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,UAAO;IA6BhE;;;;;;;OAOG;IACH,IAAI,MAAM,UAgBT;IAED,IAAI,OAAO,IAAI,MAAM,CAGpB;IAED,IAAI,YAAY,IAAI,MAAM,EAAE,CAI3B;IAED,IAAI,YAAY,IAAI,MAAM,EAAE,CAI3B;IAED,UAAU,CACR,OAAO,EAAE,wBAAwB,EACjC,KAAK,SAAU,EACf,MAAM,SAAK,EACX,MAAM,SAAI,EACV,IAAI,SAAI,GACP,IAAI;IAiBP,UAAU,CACR,OAAO,EAAE,wBAAwB,EACjC,KAAK,SAAU,EACf,SAAS,SAAK,EACd,SAAS,SAAI,GACZ,IAAI;IAmCP,YAAY,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAgB9C,OAAO,CAAC,OAAO,EAAE,wBAAwB,EAAE,KAAK,SAAS,GAAG,IAAI;IAsChE,cAAc,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI;CAMxD"}
@@ -1,4 +1,3 @@
1
- // import { createAkimaRadii, preparePointsForAkima } from 'frame.akima';
2
1
  import { Point } from './Point';
3
2
  import { Polygon } from './Polygon';
4
3
  /**
@@ -107,6 +106,21 @@ export class SortedPoints {
107
106
  point2.drawLine(context, new Point(this.Center.X, this.Center.Y + extension, this.universeCenter), color, lineWidth);
108
107
  }
109
108
  }
109
+ getExtension() {
110
+ let xMin = Infinity;
111
+ let xMax = -Infinity;
112
+ let yMin = Infinity;
113
+ let yMax = -Infinity;
114
+ if (this.polygon.Length >= 2) {
115
+ xMin = this.polygon.XMin;
116
+ xMax = this.polygon.XMax;
117
+ yMin = this.polygon.YMin;
118
+ yMax = this.polygon.YMax;
119
+ }
120
+ const xExt = xMax - xMin;
121
+ const yExt = yMax - yMin;
122
+ return { xExt, yExt };
123
+ }
110
124
  drawBox(context, color = 'blue') {
111
125
  if (this.polygon.Length >= 2) {
112
126
  const xMin = this.polygon.Points.reduce((min, p) => Math.min(min, p.X), Infinity);
package/dist/Start.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { useMachine } from 'react-robot';
2
2
  import { Point } from './Point';
3
3
  export declare function Start(props: {
4
+ origin: Point;
4
5
  machine: ReturnType<typeof useMachine>[0];
5
6
  onReset: () => void;
6
7
  onAfterLoadImage: (url: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"Start.d.ts","sourceRoot":"","sources":["../src/Start.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,wBAAgB,KAAK,CAAC,KAAK,EAAE;IAC3B,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,iBAAiB,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,cAAc,EAAE,KAAK,KAAK,IAAI,CAAC;IACpE,mBAAmB,EAAE,MAAM,IAAI,CAAC;CACjC,2CAwHA"}
1
+ {"version":3,"file":"Start.d.ts","sourceRoot":"","sources":["../src/Start.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,wBAAgB,KAAK,CAAC,KAAK,EAAE;IAC3B,MAAM,EAAE,KAAK,CAAC;IACd,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,iBAAiB,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,cAAc,EAAE,KAAK,KAAK,IAAI,CAAC;IACpE,mBAAmB,EAAE,MAAM,IAAI,CAAC;CACjC,2CAyHA"}
package/dist/Start.js CHANGED
@@ -61,5 +61,5 @@ export function Start(props) {
61
61
  flexDirection: 'column',
62
62
  gap: '10px',
63
63
  width: '90%', // Set a fixed width for the button group
64
- }, children: [_jsx(Button, { variant: "contained", disabled: isDisabled(ACTION.RESET), onClick: onReset, sx: { width: '100%' }, children: "Reset" }), _jsx(Input, { inputRef: fileInputRef, type: "file", inputProps: { accept: 'image/*' }, style: { display: 'none' }, onChange: handleFileChange, disabled: false }), _jsx(Button, { variant: "contained", disabled: isDisabled(ACTION.LOAD_IMAGE), onClick: onLoadImage, sx: { width: '100%' }, children: "Load Image" }), _jsx(Button, { id: "id.button.definePoints", variant: "contained", disabled: isDisabled(ACTION.DEFINE_POINTS), onClick: onBeforeLoadPoints, sx: { width: '100%' }, children: "Load Points" }), _jsx(StateModal, { isOpen: showModalPointsForm, onClose: onClosePointsForm, position: "top-right", children: _jsx(PointsForm, { title: "Import points", onCloseCancel: onLoadPointsCancel, onCloseContinue: onAfterLoadPoints }) })] }));
64
+ }, children: [_jsx(Button, { variant: "contained", disabled: isDisabled(ACTION.RESET), onClick: onReset, sx: { width: '100%' }, children: "Reset" }), _jsx(Input, { inputRef: fileInputRef, type: "file", inputProps: { accept: 'image/*' }, style: { display: 'none' }, onChange: handleFileChange, disabled: false }), _jsx(Button, { variant: "contained", disabled: isDisabled(ACTION.LOAD_IMAGE), onClick: onLoadImage, sx: { width: '100%' }, children: "Load Image" }), _jsx(Button, { id: "id.button.definePoints", variant: "contained", disabled: isDisabled(ACTION.DEFINE_POINTS), onClick: onBeforeLoadPoints, sx: { width: '100%' }, children: "Import RT1" }), _jsx(StateModal, { isOpen: showModalPointsForm, onClose: onClosePointsForm, position: "top-right", children: _jsx(PointsForm, { origin: props.origin, title: "Import RT1", onCloseCancel: onLoadPointsCancel, onCloseContinue: onAfterLoadPoints }) })] }));
65
65
  }
@@ -1 +1 @@
1
- {"root":["../src/action.tsx","../src/app.tsx","../src/center.tsx","../src/designer.tsx","../src/drawcanvas.tsx","../src/finish.tsx","../src/imagehandler.tsx","../src/lens.ts","../src/loadimage.tsx","../src/modaldesigner.tsx","../src/mousecoords.tsx","../src/point.ts","../src/pointsform.tsx","../src/polygon.ts","../src/scaleform.tsx","../src/scaleinput.tsx","../src/scaling.tsx","../src/showoptions.tsx","../src/sortedpoints.ts","../src/start.tsx","../src/states.tsx","../src/workflow.tsx","../src/enum.ts","../src/index.ts","../src/main.tsx","../src/types.ts","../src/vite-env.d.ts"],"version":"5.9.2"}
1
+ {"root":["../src/action.tsx","../src/app.tsx","../src/center.tsx","../src/designer.tsx","../src/drawcanvas.tsx","../src/finish.tsx","../src/imagehandler.tsx","../src/lens.ts","../src/loadimage.tsx","../src/modaldesigner.tsx","../src/mousecoords.tsx","../src/point.ts","../src/pointsform.tsx","../src/polygon.ts","../src/scaleform.tsx","../src/scaleinput.tsx","../src/scaling.tsx","../src/showoptions.tsx","../src/sortedpoints.ts","../src/start.tsx","../src/states.tsx","../src/workflow.tsx","../src/enum.ts","../src/index.ts","../src/main.tsx","../src/types.ts","../src/vite-env.d.ts"],"version":"5.9.3"}
package/dist/types.d.ts CHANGED
@@ -56,8 +56,12 @@ export type TRotationHook = {
56
56
  rotationAngle: number;
57
57
  setRotationAngle: React.Dispatch<React.SetStateAction<number>>;
58
58
  };
59
- export type TNumberValue = {
60
- value: number;
61
- setValue: React.Dispatch<React.SetStateAction<number>>;
59
+ export type TNumberHook = {
60
+ value: number | undefined;
61
+ setValue: React.Dispatch<React.SetStateAction<number | undefined>>;
62
+ };
63
+ export type TTrademarkHook = {
64
+ trademarkCenter: Point | undefined;
65
+ setTrademarkCenter: React.Dispatch<React.SetStateAction<Point | undefined>>;
62
66
  };
63
67
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,MAAM,KAAK,GAAG;IAClB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB,EAAE,CAAC,EAAE,KAAK,CAAC;IACX,EAAE,CAAC,EAAE,KAAK,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,YAAY,CAAC;IAC1B,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;CACpE,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;CAC9D,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,gBAAgB,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,mBAAmB,EAAE,KAAK,CAAC,QAAQ,CACjC,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,SAAS,CAAC,CAC1C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;CAChE,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;CACxD,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,MAAM,KAAK,GAAG;IAClB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB,EAAE,CAAC,EAAE,KAAK,CAAC;IACX,EAAE,CAAC,EAAE,KAAK,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,YAAY,CAAC;IAC1B,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;CACpE,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;CAC9D,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,gBAAgB,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,mBAAmB,EAAE,KAAK,CAAC,QAAQ,CACjC,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,SAAS,CAAC,CAC1C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;CAChE,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;CACpE,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,eAAe,EAAE,KAAK,GAAG,SAAS,CAAC;IACnC,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC;CAC7E,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frame.image",
3
- "version": "1.4.0",
3
+ "version": "1.5.1",
4
4
  "description": "A React component for drawing a frame on a canvas element.",
5
5
  "license": "MIT",
6
6
  "author": "Christian.Todd@rodenstock.com",
@@ -13,6 +13,7 @@
13
13
  "scripts": {
14
14
  "dev": "vite",
15
15
  "build": "tsc -b",
16
+ "test": "vitest",
16
17
  "doc": "typedoc --options typedoc.json --tsconfig ./tsconfig.json --logLevel Verbose",
17
18
  "build-with-vite": "tsc -b && vite build",
18
19
  "lint": "eslint .",
@@ -21,27 +22,28 @@
21
22
  "dependencies": {
22
23
  "@emotion/react": "^11.14.0",
23
24
  "@emotion/styled": "^11.14.1",
24
- "@mui/material": "^7.3.2",
25
- "frame.akima": "^1.2.1",
25
+ "@mui/material": "^7.3.5",
26
+ "frame.akima": "^2.0.1",
26
27
  "frame.nidek": "^1.1.4",
27
28
  "frame.statemachine": "^1.1.4",
28
29
  "react": "^18.3.1",
29
30
  "react-dom": "^18.3.1",
30
31
  "react-error-boundary": "^6.0.0",
31
- "react-robot": "^1.2.0"
32
+ "react-robot": "^1.2.0",
33
+ "vitest": "^4.0.14"
32
34
  },
33
35
  "devDependencies": {
34
- "@eslint/js": "^9.34.0",
36
+ "@eslint/js": "^9.39.1",
35
37
  "@types/react": "^18.0.0",
36
38
  "@types/react-dom": "^18.0.0",
37
- "@vitejs/plugin-react": "^5.0.2",
38
- "eslint": "^9.34.0",
39
- "eslint-plugin-react-hooks": "^5.2.0",
40
- "eslint-plugin-react-refresh": "^0.4.19",
41
- "globals": "^16.3.0",
42
- "typedoc": "^0.28.12",
43
- "typescript": "~5.9.2",
44
- "typescript-eslint": "^8.42.0",
45
- "vite": "^7.1.4"
39
+ "@vitejs/plugin-react": "^5.1.1",
40
+ "eslint": "^9.39.1",
41
+ "eslint-plugin-react-hooks": "^7.0.1",
42
+ "eslint-plugin-react-refresh": "^0.4.24",
43
+ "globals": "^16.5.0",
44
+ "typedoc": "^0.28.14",
45
+ "typescript": "~5.9.3",
46
+ "typescript-eslint": "^8.48.0",
47
+ "vite": "^7.2.4"
46
48
  }
47
49
  }