react-floor-mapper 0.1.6 → 0.1.8

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.
package/dist/lite.cjs ADDED
@@ -0,0 +1,480 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var reactKonva = require('react-konva');
5
+ var useImage = require('use-image');
6
+ var lucideReact = require('lucide-react');
7
+ var styled = require('styled-components');
8
+ var jsxRuntime = require('react/jsx-runtime');
9
+
10
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
+
12
+ var useImage__default = /*#__PURE__*/_interopDefault(useImage);
13
+ var styled__default = /*#__PURE__*/_interopDefault(styled);
14
+
15
+ // src/components/MapperEditor/Mapper.tsx
16
+
17
+ // src/utils/closest-segment-point.ts
18
+ var getClosestPointOnSegment = (px, py, x1, y1, x2, y2) => {
19
+ const dx = x2 - x1;
20
+ const dy = y2 - y1;
21
+ const lengthSquared = dx * dx + dy * dy;
22
+ if (lengthSquared === 0) return { x: x1, y: y1, t: 0 };
23
+ let t = ((px - x1) * dx + (py - y1) * dy) / lengthSquared;
24
+ t = Math.max(0, Math.min(1, t));
25
+ return {
26
+ x: x1 + t * dx,
27
+ y: y1 + t * dy,
28
+ t
29
+ };
30
+ };
31
+ var usePoints = (initialPoints) => {
32
+ const [points, setPoints] = react.useState(
33
+ () => initialPoints.map((p, i) => ({ id: i + 1, x: p.x, y: p.y }))
34
+ );
35
+ return { points, setPoints };
36
+ };
37
+ var useZoom = (stage) => {
38
+ const MIN_SCALE = 0.5;
39
+ const MAX_SCALE = 5;
40
+ const DEFAULT_SCALE = 1;
41
+ const [stageScale, setStageScale] = react.useState(DEFAULT_SCALE);
42
+ return {
43
+ stageScale,
44
+ setStageScale,
45
+ MIN_SCALE,
46
+ MAX_SCALE
47
+ };
48
+ };
49
+ var Container = styled__default.default.div`
50
+ overflow: hidden;
51
+ width:1200px;
52
+ height:1200px;
53
+ display: flex;
54
+ align-items: stretch;
55
+ border:1px solid #ccc;
56
+ border-radius:4px;
57
+ `;
58
+ var NavContainer = styled__default.default.div`
59
+ width:80px;
60
+ height:100%;
61
+ background:red;
62
+ flex-shrink:0;
63
+ display: flex;
64
+ justify-content: flex-start;
65
+ align-items: center;
66
+ flex-direction:column;
67
+ gap:20px;
68
+ padding:20px 0;
69
+ background:#ebebeb;
70
+ border-left:1px solid #ccc;
71
+ `;
72
+ var CanvasContainer = styled__default.default.div`
73
+ width:calc(100% - 80px);
74
+ height:100%;
75
+ overflow: hidden;
76
+ `;
77
+ var ButtonBase = styled__default.default.button`
78
+ padding:2px;
79
+ background:white;
80
+ border:none;
81
+ border-radius:8px;
82
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
83
+ cursor: pointer;
84
+ display: flex;
85
+ justify-content: center;
86
+ align-items: center;
87
+ font-size:12px;
88
+ min-width:50px;
89
+ min-height:50px;
90
+ border-left:1px solid #ccc;
91
+ &:disabled:{
92
+ opacity:0.5;
93
+ cursor:not-allowed;
94
+ }
95
+ `;
96
+ var Button = styled__default.default(ButtonBase)``;
97
+ var Mapper = ({
98
+ src = "https://konvajs.org/assets/line-building.png",
99
+ initialPoints = [],
100
+ maxWidth = 1200
101
+ }) => {
102
+ const stageRef = react.useRef(null);
103
+ const { points, setPoints } = usePoints(initialPoints);
104
+ const { stageScale, setStageScale, MAX_SCALE, MIN_SCALE } = useZoom(stageRef == null ? void 0 : stageRef.current);
105
+ const SCALE_BY = 1.2;
106
+ const [closed, setClosed] = react.useState(initialPoints.length >= 3);
107
+ const [hoveringFirst, setHoveringFirst] = react.useState(false);
108
+ const [stagePosition, setStagePosition] = react.useState({ x: 0, y: 0 });
109
+ const [dragStart, setDragStart] = react.useState(null);
110
+ const [isDraggingPoint, setIsDraggingPoint] = react.useState(false);
111
+ const [image] = useImage__default.default(src, "anonymous");
112
+ const imgW = (image == null ? void 0 : image.width) || 1;
113
+ const imgH = (image == null ? void 0 : image.height) || 1;
114
+ const scale = maxWidth / imgW;
115
+ const stageSize = { width: maxWidth, height: imgH * scale };
116
+ const DRAG_THRESHOLD = 5;
117
+ const LINE_HIT_THRESHOLD = 10;
118
+ const handleZoomIn = () => {
119
+ const stage = stageRef.current;
120
+ if (!stage) return;
121
+ const oldScale = stageScale;
122
+ const newScale = Math.min(oldScale * SCALE_BY, MAX_SCALE);
123
+ if (newScale === oldScale) return;
124
+ const centerX = stage.width() / 2;
125
+ const centerY = stage.height() / 2;
126
+ const pointTo = {
127
+ x: (centerX - stagePosition.x) / oldScale,
128
+ y: (centerY - stagePosition.y) / oldScale
129
+ };
130
+ const newPos = {
131
+ x: centerX - pointTo.x * newScale,
132
+ y: centerY - pointTo.y * newScale
133
+ };
134
+ const constrainedPos = getConstrainedPosition(newPos, newScale);
135
+ setStageScale(newScale);
136
+ setStagePosition(constrainedPos);
137
+ };
138
+ const handleZoomOut = () => {
139
+ const stage = stageRef.current;
140
+ if (!stage) return;
141
+ const oldScale = stageScale;
142
+ const newScale = Math.max(oldScale / SCALE_BY, MIN_SCALE);
143
+ if (newScale === oldScale) return;
144
+ const centerX = stage.width() / 2;
145
+ const centerY = stage.height() / 2;
146
+ const pointTo = {
147
+ x: (centerX - stagePosition.x) / oldScale,
148
+ y: (centerY - stagePosition.y) / oldScale
149
+ };
150
+ const newPos = {
151
+ x: centerX - pointTo.x * newScale,
152
+ y: centerY - pointTo.y * newScale
153
+ };
154
+ const constrainedPos = getConstrainedPosition(newPos, newScale);
155
+ setStageScale(newScale);
156
+ setStagePosition(constrainedPos);
157
+ };
158
+ const handleResetZoom = () => {
159
+ const newScale = 1;
160
+ const constrainedPos = getConstrainedPosition({ x: 0, y: 0 }, newScale);
161
+ setStageScale(newScale);
162
+ setStagePosition(constrainedPos);
163
+ };
164
+ const handleWheel = (e) => {
165
+ e.evt.preventDefault();
166
+ const stage = stageRef.current;
167
+ if (!stage) return;
168
+ const oldScale = stageScale;
169
+ const pointer = stage.getPointerPosition();
170
+ if (!pointer) return;
171
+ const mousePointTo = {
172
+ x: (pointer.x - stagePosition.x) / oldScale,
173
+ y: (pointer.y - stagePosition.y) / oldScale
174
+ };
175
+ const direction = e.evt.deltaY > 0 ? -1 : 1;
176
+ const newScale = direction > 0 ? Math.min(oldScale * SCALE_BY, MAX_SCALE) : Math.max(oldScale / SCALE_BY, MIN_SCALE);
177
+ if (newScale === oldScale) return;
178
+ const newPos = {
179
+ x: pointer.x - mousePointTo.x * newScale,
180
+ y: pointer.y - mousePointTo.y * newScale
181
+ };
182
+ const constrainedPos = getConstrainedPosition(newPos, newScale);
183
+ setStageScale(newScale);
184
+ setStagePosition(constrainedPos);
185
+ };
186
+ const getConstrainedPosition = (pos, currentScale) => {
187
+ const stage = stageRef.current;
188
+ if (!stage) return pos;
189
+ const stageWidth = stage.width();
190
+ const stageHeight = stage.height();
191
+ const imageWidth = stageSize.width * currentScale;
192
+ const imageHeight = stageSize.height * currentScale;
193
+ let newX = pos.x;
194
+ let newY = pos.y;
195
+ if (imageWidth > stageWidth) {
196
+ if (newX > 0) newX = 0;
197
+ if (newX < stageWidth - imageWidth) newX = stageWidth - imageWidth;
198
+ } else {
199
+ newX = (stageWidth - imageWidth) / 2;
200
+ }
201
+ if (imageHeight > stageHeight) {
202
+ if (newY > 0) newY = 0;
203
+ if (newY < stageHeight - imageHeight) newY = stageHeight - imageHeight;
204
+ } else {
205
+ newY = (stageHeight - imageHeight) / 2;
206
+ }
207
+ return { x: newX, y: newY };
208
+ };
209
+ const findLineSegmentNearClick = (clickX, clickY) => {
210
+ if (points.length < 2) return null;
211
+ const threshold = LINE_HIT_THRESHOLD / (scale * stageScale);
212
+ const segments = [];
213
+ for (let i = 0; i < points.length - 1; i++) {
214
+ segments.push({ start: i, end: i + 1 });
215
+ }
216
+ if (closed) {
217
+ segments.push({ start: points.length - 1, end: 0 });
218
+ }
219
+ for (const segment of segments) {
220
+ const p1 = points[segment.start];
221
+ const p2 = points[segment.end];
222
+ const closest = getClosestPointOnSegment(clickX, clickY, p1.x, p1.y, p2.x, p2.y);
223
+ const distance = Math.hypot(closest.x - clickX, closest.y - clickY);
224
+ if (distance < threshold) {
225
+ return {
226
+ segmentIndex: segment.start,
227
+ insertPosition: closest.t,
228
+ point: { x: closest.x, y: closest.y }
229
+ };
230
+ }
231
+ }
232
+ return null;
233
+ };
234
+ react.useEffect(() => {
235
+ if (image) {
236
+ const initialPos = getConstrainedPosition({ x: 0, y: 0 }, 1);
237
+ setStagePosition(initialPos);
238
+ }
239
+ }, [image]);
240
+ react.useEffect(() => {
241
+ const handleKeyDown = (e) => {
242
+ if (e.ctrlKey || e.metaKey) {
243
+ if (e.key === "=" || e.key === "+") {
244
+ e.preventDefault();
245
+ handleZoomIn();
246
+ } else if (e.key === "-") {
247
+ e.preventDefault();
248
+ handleZoomOut();
249
+ } else if (e.key === "0") {
250
+ e.preventDefault();
251
+ handleResetZoom();
252
+ }
253
+ }
254
+ };
255
+ window.addEventListener("keydown", handleKeyDown);
256
+ return () => window.removeEventListener("keydown", handleKeyDown);
257
+ }, [stageScale, stagePosition]);
258
+ const handleStageDragStart = (e) => {
259
+ const clickedShape = e.target;
260
+ if (clickedShape && clickedShape.name() === "point") {
261
+ e.target.stopDrag();
262
+ return;
263
+ }
264
+ const stage = e.target.getStage();
265
+ if (!stage) return;
266
+ const pos = stage.getPointerPosition();
267
+ if (pos) {
268
+ setDragStart(pos);
269
+ }
270
+ };
271
+ const handleStageDragEnd = (e) => {
272
+ const newPos = {
273
+ x: e.target.x(),
274
+ y: e.target.y()
275
+ };
276
+ const constrainedPos = getConstrainedPosition(newPos, stageScale);
277
+ setStagePosition(constrainedPos);
278
+ setDragStart(null);
279
+ };
280
+ const toImageCoords = (stage) => {
281
+ if (!stage) return { x: 0, y: 0 };
282
+ const pos = stage.getPointerPosition();
283
+ if (!pos) return { x: 0, y: 0 };
284
+ const x = (pos.x - stagePosition.x) / (scale * stageScale);
285
+ const y = (pos.y - stagePosition.y) / (scale * stageScale);
286
+ return { x, y };
287
+ };
288
+ const linePointsScaled = react.useMemo(() => {
289
+ const flat = points.flatMap((p) => [p.x * scale, p.y * scale]);
290
+ return flat;
291
+ }, [points, scale]);
292
+ const commit = (nextPoints) => {
293
+ setPoints(nextPoints);
294
+ };
295
+ const handlePointDragStart = (e) => {
296
+ e.cancelBubble = true;
297
+ setIsDraggingPoint(true);
298
+ };
299
+ const handlePointDragMove = (id, e) => {
300
+ const newX = e.target.x() / scale;
301
+ const newY = e.target.y() / scale;
302
+ const updatedPoints = points.map(
303
+ (p) => p.id === id ? { ...p, x: newX, y: newY } : p
304
+ );
305
+ setPoints(updatedPoints);
306
+ };
307
+ const handlePointDragEnd = (e) => {
308
+ e.cancelBubble = true;
309
+ setIsDraggingPoint(false);
310
+ };
311
+ const handleStageMouseDown = (e) => {
312
+ if (!image) return;
313
+ const clickedShape = e.target;
314
+ if (clickedShape && clickedShape.name() === "point") {
315
+ if (!closed) {
316
+ const clickedIndex = points.findIndex(
317
+ (p) => Math.abs(p.x * scale - clickedShape.x()) < 1 && Math.abs(p.y * scale - clickedShape.y()) < 1
318
+ );
319
+ if (clickedIndex === 0 && points.length >= 3) {
320
+ setClosed(true);
321
+ setHoveringFirst(false);
322
+ }
323
+ }
324
+ return;
325
+ }
326
+ const stage = e.target.getStage();
327
+ if (!stage) return;
328
+ const pos = stage.getPointerPosition();
329
+ if (pos) {
330
+ setDragStart(pos);
331
+ }
332
+ };
333
+ const handleStageMouseUp = (e) => {
334
+ if (!image || isDraggingPoint) return;
335
+ const clickedShape = e.target;
336
+ if (clickedShape && clickedShape.name() === "point") {
337
+ return;
338
+ }
339
+ if (dragStart) {
340
+ const stage = e.target.getStage();
341
+ if (!stage) return;
342
+ const currentPos = stage.getPointerPosition();
343
+ if (currentPos) {
344
+ const dx = currentPos.x - dragStart.x;
345
+ const dy = currentPos.y - dragStart.y;
346
+ const distance = Math.sqrt(dx * dx + dy * dy);
347
+ if (distance < DRAG_THRESHOLD) {
348
+ const p = toImageCoords(stage);
349
+ const lineHit = findLineSegmentNearClick(p.x, p.y);
350
+ if (lineHit) {
351
+ const newPoint = {
352
+ id: Date.now(),
353
+ x: lineHit.point.x,
354
+ y: lineHit.point.y
355
+ };
356
+ const newPoints = [...points];
357
+ newPoints.splice(lineHit.segmentIndex + 1, 0, newPoint);
358
+ commit(newPoints);
359
+ } else if (!closed) {
360
+ const next = [...points, { id: Date.now(), x: p.x, y: p.y }];
361
+ commit(next);
362
+ }
363
+ }
364
+ }
365
+ setDragStart(null);
366
+ }
367
+ };
368
+ const handleMouseMove = (e) => {
369
+ if (closed || points.length < 3) {
370
+ setHoveringFirst(false);
371
+ return;
372
+ }
373
+ const stage = e.target.getStage();
374
+ const p = toImageCoords(stage);
375
+ const fp = points[0];
376
+ const dx = (p.x - fp.x) * scale * stageScale;
377
+ const dy = (p.y - fp.y) * scale * stageScale;
378
+ const dist = Math.hypot(dx, dy);
379
+ setHoveringFirst(dist < 15);
380
+ };
381
+ return /* @__PURE__ */ jsxRuntime.jsxs(Container, { children: [
382
+ /* @__PURE__ */ jsxRuntime.jsx(CanvasContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(
383
+ reactKonva.Stage,
384
+ {
385
+ ref: stageRef,
386
+ width: 1200,
387
+ height: 1200,
388
+ onMouseDown: handleStageMouseDown,
389
+ onMouseUp: handleStageMouseUp,
390
+ onMouseMove: handleMouseMove,
391
+ onWheel: handleWheel,
392
+ scaleX: stageScale,
393
+ scaleY: stageScale,
394
+ x: stagePosition.x,
395
+ y: stagePosition.y,
396
+ draggable: !isDraggingPoint,
397
+ onDragStart: handleStageDragStart,
398
+ onDragEnd: handleStageDragEnd,
399
+ dragBoundFunc: (pos) => getConstrainedPosition(pos, stageScale),
400
+ children: /* @__PURE__ */ jsxRuntime.jsxs(reactKonva.Layer, { children: [
401
+ /* @__PURE__ */ jsxRuntime.jsx(
402
+ reactKonva.Image,
403
+ {
404
+ image,
405
+ width: stageSize.width,
406
+ height: stageSize.height,
407
+ listening: false
408
+ }
409
+ ),
410
+ points.length >= 2 && /* @__PURE__ */ jsxRuntime.jsx(
411
+ reactKonva.Line,
412
+ {
413
+ points: linePointsScaled,
414
+ closed,
415
+ stroke: "#2563eb",
416
+ strokeWidth: 2 / stageScale,
417
+ lineCap: "round",
418
+ lineJoin: "round",
419
+ tension: 0,
420
+ fill: closed ? "rgba(37, 99, 235, 0.3)" : void 0,
421
+ hitStrokeWidth: LINE_HIT_THRESHOLD / stageScale
422
+ }
423
+ ),
424
+ /* @__PURE__ */ jsxRuntime.jsx(reactKonva.Group, { children: points.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx(
425
+ reactKonva.Circle,
426
+ {
427
+ name: "point",
428
+ x: p.x * scale,
429
+ y: p.y * scale,
430
+ radius: (i === 0 && hoveringFirst ? 10 : 6) / stageScale,
431
+ fill: i === 0 ? "#ef4444" : "#7e9de1",
432
+ stroke: i === 0 && hoveringFirst ? "#fbbf24" : void 0,
433
+ strokeWidth: i === 0 && hoveringFirst ? 2 / stageScale : 0,
434
+ draggable: true,
435
+ onDragStart: handlePointDragStart,
436
+ onDragMove: (e) => handlePointDragMove(p.id, e),
437
+ onDragEnd: handlePointDragEnd
438
+ },
439
+ p.id
440
+ )) })
441
+ ] })
442
+ }
443
+ ) }),
444
+ /* @__PURE__ */ jsxRuntime.jsxs(NavContainer, { children: [
445
+ /* @__PURE__ */ jsxRuntime.jsx(
446
+ Button,
447
+ {
448
+ onClick: handleZoomIn,
449
+ disabled: stageScale >= MAX_SCALE,
450
+ title: "Zoom In (Ctrl/Cmd + +)",
451
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomIn, { style: { width: "20px", height: "20px" } })
452
+ }
453
+ ),
454
+ /* @__PURE__ */ jsxRuntime.jsx(
455
+ Button,
456
+ {
457
+ onClick: handleZoomOut,
458
+ disabled: stageScale <= MIN_SCALE,
459
+ title: "Zoom Out (Ctrl/Cmd + -)",
460
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomOut, { style: { width: "20px", height: "20px" } })
461
+ }
462
+ ),
463
+ /* @__PURE__ */ jsxRuntime.jsxs(
464
+ Button,
465
+ {
466
+ onClick: handleResetZoom,
467
+ title: "Reset Zoom (Ctrl/Cmd + 0)",
468
+ children: [
469
+ Math.round(stageScale * 100),
470
+ "%"
471
+ ]
472
+ }
473
+ )
474
+ ] })
475
+ ] });
476
+ };
477
+
478
+ exports.Mapper = Mapper;
479
+ //# sourceMappingURL=lite.cjs.map
480
+ //# sourceMappingURL=lite.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/closest-segment-point.ts","../src/components/MapperEditor/hooks/usePoints.ts","../src/components/MapperEditor/hooks/useZoom.ts","../src/components/MapperEditor/Mapper.style.tsx","../src/components/MapperEditor/Mapper.tsx"],"names":["useState","styled","useRef","useImage","useEffect","useMemo","jsx","Stage","Layer","KonvaImage","Line","Group","Circle","ZoomIn","ZoomOut","jsxs"],"mappings":"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","file":"lite.cjs","sourcesContent":["export const getClosestPointOnSegment = (\n px: number, py: number,\n x1: number, y1: number,\n x2: number, y2: number\n) => {\n const dx = x2 - x1;\n const dy = y2 - y1;\n const lengthSquared = dx * dx + dy * dy;\n \n if (lengthSquared === 0) return { x: x1, y: y1, t: 0 };\n \n let t = ((px - x1) * dx + (py - y1) * dy) / lengthSquared;\n t = Math.max(0, Math.min(1, t));\n \n return {\n x: x1 + t * dx,\n y: y1 + t * dy,\n t\n };\n};","import { useState } from \"react\";\nimport { Point, Points } from \"../../../types/points.type\";\n\nexport const usePoints = (initialPoints: Omit<Point, \"id\">[]) => {\n const [points, setPoints] = useState<Points>(() =>\n initialPoints.map((p, i) => ({ id: i + 1, x: p.x, y: p.y }))\n );\n\n return { points, setPoints };\n}","import Konva from \"konva\";\nimport { KonvaEventObject } from \"konva/lib/Node\";\nimport { useState } from \"react\";\n\nexport const useZoom = (stage:Konva.Stage | null) => {\n const MIN_SCALE = 0.5;\n const MAX_SCALE = 5;\n const DEFAULT_SCALE = 1;\n \n const [stageScale, setStageScale] = useState(DEFAULT_SCALE);\n\n return{\n stageScale,\n setStageScale,\n MIN_SCALE,\n MAX_SCALE,\n }\n}","import styled from \"styled-components\";\n\nexport const Container = styled.div`\n overflow: hidden;\n width:1200px;\n height:1200px;\n display: flex;\n align-items: stretch;\n border:1px solid #ccc;\n border-radius:4px;\n`;\n\nexport const NavContainer = styled.div`\n width:80px;\n height:100%;\n background:red;\n flex-shrink:0;\n display: flex;\n justify-content: flex-start;\n align-items: center;\n flex-direction:column;\n gap:20px;\n padding:20px 0;\n background:#ebebeb;\n border-left:1px solid #ccc;\n`\n\nexport const CanvasContainer = styled.div`\n width:calc(100% - 80px);\n height:100%;\n overflow: hidden;\n`\n\nexport const ButtonBase = styled.button`\n padding:2px;\n background:white;\n border:none;\n border-radius:8px;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n cursor: pointer;\n display: flex;\n justify-content: center;\n align-items: center;\n font-size:12px;\n min-width:50px;\n min-height:50px;\n border-left:1px solid #ccc;\n &:disabled:{\n opacity:0.5;\n cursor:not-allowed;\n }\n`\n\nexport const Button = styled(ButtonBase)``;","import { KonvaEventObject } from \"konva/lib/Node\";\nimport React, { useMemo, useState, useRef, useEffect } from \"react\";\nimport { Stage, Layer, Image as KonvaImage, Circle, Line, Group } from \"react-konva\";\nimport useImage from \"use-image\";\nimport Konva from \"konva\";\nimport { ZoomIn, ZoomOut } from \"lucide-react\";\nimport { getClosestPointOnSegment } from \"../../utils/closest-segment-point\";\nimport { usePoints } from \"./hooks/usePoints\";\nimport { Point, Points } from \"../../types/points.type\";\nimport { useZoom } from \"./hooks/useZoom\";\nimport { Button, CanvasContainer, Container, NavContainer } from \"./Mapper.style\";\n\nexport interface MapperProps {\n src?: string;\n initialPoints?: Omit<Point, \"id\">[];\n maxWidth?: number;\n}\n\nexport const Mapper = ({\n src = \"https://konvajs.org/assets/line-building.png\",\n initialPoints = [], \n maxWidth = 1200,\n}: MapperProps) => {\n const stageRef = useRef<Konva.Stage>(null);\n const { points, setPoints } = usePoints(initialPoints);\n const { stageScale, setStageScale, MAX_SCALE, MIN_SCALE } = useZoom(stageRef?.current);\n const SCALE_BY = 1.2;\n\n const [closed, setClosed] = useState(initialPoints.length >= 3);\n \n const [hoveringFirst, setHoveringFirst] = useState(false);\n const [stagePosition, setStagePosition] = useState({ x: 0, y: 0 });\n const [dragStart, setDragStart] = useState<{ x: number; y: number } | null>(null);\n const [isDraggingPoint, setIsDraggingPoint] = useState(false);\n \n \n const [image] = useImage(src, \"anonymous\");\n const imgW = image?.width || 1;\n const imgH = image?.height || 1;\n const scale = maxWidth / imgW;\n const stageSize = { width: maxWidth, height: imgH * scale } ;\n\n \n const DRAG_THRESHOLD = 5;\n const LINE_HIT_THRESHOLD = 10;\n\n const handleZoomIn = () => {\n const stage = stageRef.current;\n if (!stage) return;\n\n const oldScale = stageScale;\n const newScale = Math.min(oldScale * SCALE_BY, MAX_SCALE);\n\n if (newScale === oldScale) return;\n\n const centerX = stage.width() / 2;\n const centerY = stage.height() / 2;\n\n const pointTo = {\n x: (centerX - stagePosition.x) / oldScale,\n y: (centerY - stagePosition.y) / oldScale,\n };\n\n const newPos = {\n x: centerX - pointTo.x * newScale,\n y: centerY - pointTo.y * newScale,\n };\n\n const constrainedPos = getConstrainedPosition(newPos, newScale);\n setStageScale(newScale);\n setStagePosition(constrainedPos);\n };\n \n const handleZoomOut = () => {\n const stage = stageRef.current;\n if (!stage) return;\n \n const oldScale = stageScale;\n const newScale = Math.max(oldScale / SCALE_BY, MIN_SCALE);\n \n if (newScale === oldScale) return;\n \n const centerX = stage.width() / 2;\n const centerY = stage.height() / 2;\n \n const pointTo = {\n x: (centerX - stagePosition.x) / oldScale,\n y: (centerY - stagePosition.y) / oldScale,\n };\n \n const newPos = {\n x: centerX - pointTo.x * newScale,\n y: centerY - pointTo.y * newScale,\n };\n \n const constrainedPos = getConstrainedPosition(newPos, newScale);\n setStageScale(newScale);\n setStagePosition(constrainedPos);\n };\n \n const handleResetZoom = () => {\n const newScale = 1;\n const constrainedPos = getConstrainedPosition({ x: 0, y: 0 }, newScale);\n setStageScale(newScale);\n setStagePosition(constrainedPos);\n };\n \n const handleWheel = (e: KonvaEventObject<WheelEvent>) => {\n e.evt.preventDefault();\n \n const stage = stageRef.current;\n if (!stage) return;\n \n const oldScale = stageScale;\n const pointer = stage.getPointerPosition();\n if (!pointer) return;\n \n const mousePointTo = {\n x: (pointer.x - stagePosition.x) / oldScale,\n y: (pointer.y - stagePosition.y) / oldScale,\n };\n \n const direction = e.evt.deltaY > 0 ? -1 : 1;\n const newScale = direction > 0 \n ? Math.min(oldScale * SCALE_BY, MAX_SCALE)\n : Math.max(oldScale / SCALE_BY, MIN_SCALE);\n \n if (newScale === oldScale) return;\n \n const newPos = {\n x: pointer.x - mousePointTo.x * newScale,\n y: pointer.y - mousePointTo.y * newScale,\n };\n \n const constrainedPos = getConstrainedPosition(newPos, newScale);\n setStageScale(newScale);\n setStagePosition(constrainedPos);\n };\n\n // Function to constrain position within bounds\n const getConstrainedPosition = (pos: { x: number; y: number }, currentScale: number) => {\n const stage = stageRef.current;\n if (!stage) return pos;\n\n const stageWidth = stage.width();\n const stageHeight = stage.height();\n const imageWidth = stageSize.width * currentScale;\n const imageHeight = stageSize.height * currentScale;\n\n let newX = pos.x;\n let newY = pos.y;\n\n // Constrain X axis\n if (imageWidth > stageWidth) {\n if (newX > 0) newX = 0;\n if (newX < stageWidth - imageWidth) newX = stageWidth - imageWidth;\n } else {\n newX = (stageWidth - imageWidth) / 2;\n }\n\n // Constrain Y axis\n if (imageHeight > stageHeight) {\n if (newY > 0) newY = 0;\n if (newY < stageHeight - imageHeight) newY = stageHeight - imageHeight;\n } else {\n newY = (stageHeight - imageHeight) / 2;\n }\n\n return { x: newX, y: newY };\n };\n\n\n // Function to check if click is near a line segment\n const findLineSegmentNearClick = (clickX: number, clickY: number) => {\n if (points.length < 2) return null;\n\n const threshold = LINE_HIT_THRESHOLD / (scale * stageScale);\n \n const segments = [];\n for (let i = 0; i < points.length - 1; i++) {\n segments.push({ start: i, end: i + 1 });\n }\n \n // If closed, add segment from last to first\n if (closed) {\n segments.push({ start: points.length - 1, end: 0 });\n }\n\n for (const segment of segments) {\n const p1 = points[segment.start];\n const p2 = points[segment.end];\n \n const closest = getClosestPointOnSegment(clickX, clickY, p1.x, p1.y, p2.x, p2.y);\n const distance = Math.hypot(closest.x - clickX, closest.y - clickY);\n \n if (distance < threshold) {\n return {\n segmentIndex: segment.start,\n insertPosition: closest.t,\n point: { x: closest.x, y: closest.y }\n };\n }\n }\n \n return null;\n };\n\n // Initialize position on image load\n useEffect(() => {\n if (image) {\n const initialPos = getConstrainedPosition({ x: 0, y: 0 }, 1);\n setStagePosition(initialPos);\n }\n }, [image]);\n\n // Keyboard shortcuts\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.ctrlKey || e.metaKey) {\n if (e.key === \"=\" || e.key === \"+\") {\n e.preventDefault();\n handleZoomIn();\n } else if (e.key === \"-\") {\n e.preventDefault();\n handleZoomOut();\n } else if (e.key === \"0\") {\n e.preventDefault();\n handleResetZoom();\n }\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [stageScale, stagePosition]);\n\n const handleStageDragStart = (e: KonvaEventObject<MouseEvent>) => {\n // Only allow stage dragging if not clicking on a point\n const clickedShape = e.target;\n if (clickedShape && clickedShape.name() === \"point\") {\n e.target.stopDrag();\n return;\n }\n\n const stage = e.target.getStage();\n if (!stage) return;\n \n const pos = stage.getPointerPosition();\n if (pos) {\n setDragStart(pos);\n }\n };\n\n const handleStageDragEnd = (e: KonvaEventObject<DragEvent>) => {\n const newPos = {\n x: e.target.x(),\n y: e.target.y(),\n };\n const constrainedPos = getConstrainedPosition(newPos, stageScale);\n setStagePosition(constrainedPos);\n setDragStart(null);\n };\n\n const toImageCoords = (stage: Konva.Stage | null): { x: number; y: number } => {\n if (!stage) return { x: 0, y: 0 };\n const pos = stage.getPointerPosition();\n if (!pos) return { x: 0, y: 0 };\n \n const x = (pos.x - stagePosition.x) / (scale * stageScale);\n const y = (pos.y - stagePosition.y) / (scale * stageScale);\n \n return { x, y };\n };\n\n const linePointsScaled = useMemo(() => {\n const flat = points.flatMap((p) => [p.x * scale, p.y * scale]);\n return flat;\n }, [points, scale]);\n\n const commit = (nextPoints: Points) => {\n setPoints(nextPoints);\n };\n\n const handlePointDragStart = (e: KonvaEventObject<DragEvent>) => {\n e.cancelBubble = true; // Prevent stage from dragging\n setIsDraggingPoint(true);\n };\n\n const handlePointDragMove = (id: number, e: KonvaEventObject<DragEvent>) => {\n const newX = e.target.x() / scale;\n const newY = e.target.y() / scale;\n \n const updatedPoints = points.map((p) => \n p.id === id ? { ...p, x: newX, y: newY } : p\n );\n \n setPoints(updatedPoints);\n };\n\n const handlePointDragEnd = (e: KonvaEventObject<DragEvent>) => {\n e.cancelBubble = true; // Prevent stage from processing this event\n setIsDraggingPoint(false);\n };\n\n const handleStageMouseDown = (e: KonvaEventObject<MouseEvent>) => {\n if (!image) return;\n\n const clickedShape = e.target;\n \n // Check if we clicked on a point\n if (clickedShape && clickedShape.name() === \"point\") {\n if (!closed) {\n const clickedIndex = points.findIndex((p) => \n Math.abs(p.x * scale - clickedShape.x()) < 1 && \n Math.abs(p.y * scale - clickedShape.y()) < 1\n );\n \n if (clickedIndex === 0 && points.length >= 3) {\n setClosed(true);\n setHoveringFirst(false);\n }\n }\n return;\n }\n\n // Track drag start for stage\n const stage = e.target.getStage();\n if (!stage) return;\n \n const pos = stage.getPointerPosition();\n if (pos) {\n setDragStart(pos);\n }\n };\n\n const handleStageMouseUp = (e: KonvaEventObject<MouseEvent>) => {\n if (!image || isDraggingPoint) return;\n\n const clickedShape = e.target;\n \n // Don't add point if clicked on a point\n if (clickedShape && clickedShape.name() === \"point\") {\n return;\n }\n\n // Check if this was a drag or a click\n if (dragStart) {\n const stage = e.target.getStage();\n if (!stage) return;\n \n const currentPos = stage.getPointerPosition();\n if (currentPos) {\n const dx = currentPos.x - dragStart.x;\n const dy = currentPos.y - dragStart.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n \n // If moved less than threshold, it's a click\n if (distance < DRAG_THRESHOLD) {\n const p = toImageCoords(stage);\n \n // Check if click is near an existing line\n const lineHit = findLineSegmentNearClick(p.x, p.y);\n \n if (lineHit) {\n // Insert point into the line\n const newPoint = {\n id: Date.now(),\n x: lineHit.point.x,\n y: lineHit.point.y\n };\n \n const newPoints = [...points];\n newPoints.splice(lineHit.segmentIndex + 1, 0, newPoint);\n commit(newPoints);\n } else if (!closed) {\n // Add point to the end (only if not closed)\n const next = [...points, { id: Date.now(), x: p.x, y: p.y }];\n commit(next);\n }\n }\n }\n \n setDragStart(null);\n }\n };\n\n const handleMouseMove = (e: KonvaEventObject<MouseEvent>) => {\n if (closed || points.length < 3) {\n setHoveringFirst(false);\n return;\n }\n\n const stage = e.target.getStage();\n const p = toImageCoords(stage);\n const fp = points[0];\n const dx = (p.x - fp.x) * scale * stageScale;\n const dy = (p.y - fp.y) * scale * stageScale;\n const dist = Math.hypot(dx, dy);\n\n setHoveringFirst(dist < 15);\n };\n\n return (\n <Container>\n <CanvasContainer>\n <Stage\n ref={stageRef}\n width={1200}\n height={1200}\n onMouseDown={handleStageMouseDown}\n onMouseUp={handleStageMouseUp}\n onMouseMove={handleMouseMove}\n onWheel={handleWheel}\n scaleX={stageScale}\n scaleY={stageScale}\n x={stagePosition.x}\n y={stagePosition.y}\n draggable={!isDraggingPoint}\n onDragStart={handleStageDragStart}\n onDragEnd={handleStageDragEnd}\n dragBoundFunc={(pos) => getConstrainedPosition(pos, stageScale)}\n >\n <Layer>\n <KonvaImage \n image={image} \n width={stageSize.width} \n height={stageSize.height} \n listening={false} \n />\n\n {points.length >= 2 && (\n <Line\n points={linePointsScaled}\n closed={closed}\n stroke=\"#2563eb\"\n strokeWidth={2 / stageScale}\n lineCap=\"round\"\n lineJoin=\"round\"\n tension={0}\n fill={closed ? \"rgba(37, 99, 235, 0.3)\" : undefined}\n hitStrokeWidth={LINE_HIT_THRESHOLD / stageScale}\n />\n )}\n\n <Group>\n {points.map((p, i) => (\n <Circle\n key={p.id}\n name=\"point\"\n x={p.x * scale}\n y={p.y * scale}\n radius={(i === 0 && hoveringFirst ? 10 : 6) / stageScale}\n fill={i === 0 ? \"#ef4444\" : \"#7e9de1\"}\n stroke={i === 0 && hoveringFirst ? \"#fbbf24\" : undefined}\n strokeWidth={i === 0 && hoveringFirst ? 2 / stageScale : 0}\n draggable={true}\n onDragStart={handlePointDragStart}\n onDragMove={(e) => handlePointDragMove(p.id, e)}\n onDragEnd={handlePointDragEnd}\n />\n ))}\n </Group>\n </Layer>\n </Stage>\n </CanvasContainer>\n <NavContainer>\n <Button\n onClick={handleZoomIn}\n disabled={stageScale >= MAX_SCALE}\n title=\"Zoom In (Ctrl/Cmd + +)\"\n >\n <ZoomIn style={{ width: '20px', height: '20px' }} />\n </Button>\n <Button\n onClick={handleZoomOut}\n disabled={stageScale <= MIN_SCALE}\n title=\"Zoom Out (Ctrl/Cmd + -)\"\n >\n <ZoomOut style={{ width: '20px', height: '20px' }} />\n </Button>\n <Button\n onClick={handleResetZoom}\n title=\"Reset Zoom (Ctrl/Cmd + 0)\"\n >\n {Math.round(stageScale * 100)}%\n </Button>\n </NavContainer>\n </Container>\n );\n};"]}
@@ -0,0 +1,16 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type Point = {
4
+ id: number;
5
+ x: number;
6
+ y: number;
7
+ };
8
+
9
+ interface MapperProps {
10
+ src?: string;
11
+ initialPoints?: Omit<Point, "id">[];
12
+ maxWidth?: number;
13
+ }
14
+ declare const Mapper: ({ src, initialPoints, maxWidth, }: MapperProps) => react_jsx_runtime.JSX.Element;
15
+
16
+ export { Mapper, type MapperProps };
package/dist/lite.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type Point = {
4
+ id: number;
5
+ x: number;
6
+ y: number;
7
+ };
8
+
9
+ interface MapperProps {
10
+ src?: string;
11
+ initialPoints?: Omit<Point, "id">[];
12
+ maxWidth?: number;
13
+ }
14
+ declare const Mapper: ({ src, initialPoints, maxWidth, }: MapperProps) => react_jsx_runtime.JSX.Element;
15
+
16
+ export { Mapper, type MapperProps };