@elixpo/lixsketch 5.6.11 → 5.6.12
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/react/Arrow-YIOAH45F.js +9 -0
- package/dist/react/{Circle-5WL5HZA5.js → Circle-BZANVNWQ.js} +3 -3
- package/dist/react/{CopyPaste-V7AY56H3.js → CopyPaste-IY5TF5Z2.js} +6 -6
- package/dist/react/{EraserTrail-PA6IQLQN.js → EraserTrail-F3ZJNWNL.js} +2 -2
- package/dist/react/{Line-YONPLUYT.js → Line-7IGMPC5Q.js} +3 -3
- package/dist/react/{Rectangle-7KMA3SC6.js → Rectangle-G3MPA72T.js} +3 -3
- package/dist/react/{SceneSerializer-7O72LEZP.js → SceneSerializer-X5GJFI2E.js} +6 -6
- package/dist/react/{SketchEngine-VTWURP2K.js → SketchEngine-6UBUCW5L.js} +10 -10
- package/dist/react/{chunk-TCWCC4Z4.js → chunk-3ROBBYUS.js} +30 -12
- package/dist/react/chunk-3ROBBYUS.js.map +7 -0
- package/dist/react/{chunk-JYBJXTLM.js → chunk-6DJ2UFEY.js} +4 -3
- package/dist/react/chunk-6DJ2UFEY.js.map +7 -0
- package/dist/react/chunk-6KNC7RDT.js +59 -0
- package/dist/react/chunk-6KNC7RDT.js.map +7 -0
- package/dist/react/{chunk-5OUBTHHO.js → chunk-PK7MU63Q.js} +33 -12
- package/dist/react/chunk-PK7MU63Q.js.map +7 -0
- package/dist/react/{chunk-WCA3FGWE.js → chunk-YXJMIL6G.js} +4 -3
- package/dist/react/chunk-YXJMIL6G.js.map +7 -0
- package/dist/react/{chunk-VJDNKJBX.js → chunk-ZTSW4DOB.js} +4 -3
- package/dist/react/chunk-ZTSW4DOB.js.map +7 -0
- package/dist/react/{eraserTool-2GS2LQCS.js → eraserTool-P6WR35AE.js} +11 -5
- package/dist/react/eraserTool-P6WR35AE.js.map +7 -0
- package/dist/react/index.js +41 -8
- package/dist/react/index.js.map +3 -3
- package/dist/react/{laserTool-XVMV63AV.js → laserTool-L3MNCPTS.js} +15 -8
- package/dist/react/laserTool-L3MNCPTS.js.map +7 -0
- package/package.json +1 -1
- package/src/core/EraserTrail.js +36 -11
- package/src/core/ShapeLabelLayout.js +42 -0
- package/src/react/components/sidebars/ShapeSidebar.jsx +28 -4
- package/src/react/store/useSketchStore.js +5 -1
- package/src/shapes/Arrow.js +2 -1
- package/src/shapes/Circle.js +2 -1
- package/src/shapes/Line.js +2 -1
- package/src/shapes/Rectangle.js +32 -10
- package/src/tools/eraserTool.js +9 -3
- package/src/tools/laserTool.js +14 -8
- package/dist/react/Arrow-QMR77LGQ.js +0 -9
- package/dist/react/chunk-5OUBTHHO.js.map +0 -7
- package/dist/react/chunk-JYBJXTLM.js.map +0 -7
- package/dist/react/chunk-M7OYYJC6.js +0 -17
- package/dist/react/chunk-M7OYYJC6.js.map +0 -7
- package/dist/react/chunk-TCWCC4Z4.js.map +0 -7
- package/dist/react/chunk-VJDNKJBX.js.map +0 -7
- package/dist/react/chunk-WCA3FGWE.js.map +0 -7
- package/dist/react/eraserTool-2GS2LQCS.js.map +0 -7
- package/dist/react/laserTool-XVMV63AV.js.map +0 -7
- /package/dist/react/{Arrow-QMR77LGQ.js.map → Arrow-YIOAH45F.js.map} +0 -0
- /package/dist/react/{Circle-5WL5HZA5.js.map → Circle-BZANVNWQ.js.map} +0 -0
- /package/dist/react/{CopyPaste-V7AY56H3.js.map → CopyPaste-IY5TF5Z2.js.map} +0 -0
- /package/dist/react/{EraserTrail-PA6IQLQN.js.map → EraserTrail-F3ZJNWNL.js.map} +0 -0
- /package/dist/react/{Line-YONPLUYT.js.map → Line-7IGMPC5Q.js.map} +0 -0
- /package/dist/react/{Rectangle-7KMA3SC6.js.map → Rectangle-G3MPA72T.js.map} +0 -0
- /package/dist/react/{SceneSerializer-7O72LEZP.js.map → SceneSerializer-X5GJFI2E.js.map} +0 -0
- /package/dist/react/{SketchEngine-VTWURP2K.js.map → SketchEngine-6UBUCW5L.js.map} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/shapes/Circle.js"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable */\nimport { registerRotationAnchor } from '../core/ScreenSpaceControls.js';\nimport { canvasToLocal, localToCanvas } from '../core/CanvasSpace.js';\nimport { DEFAULT_SHAPE_LABEL_FONT_SIZE } from '../core/ShapeLabelLayout.js';\nimport { resolveThemeLabelColor } from '../utils/themeColors.js';\n// Circle shape class - extracted from drawCircle.js\n// Depends on globals: svg, shapes, rough, currentShape, currentZoom, rc\n\nconst rc = rough.svg(svg);\nlet isDraggingShapeCircle = false;\nlet isResizingShapeCircle = false;\nlet isRotatingShapeCircle = false;\nlet hoveredFrameCircle = null;\nconst colorOptionsCircle = document.querySelectorAll(\".circleStrokeSpan\");\nconst backgroundColorOptionsCircle = document.querySelectorAll(\".circleBackgroundSpan\");\nconst fillStyleOptionsCircle = document.querySelectorAll(\".circleFillStyleSpan\");\nconst strokeThicknessValueCircle = document.querySelectorAll(\".circleStrokeThickSpan\");\nconst outlineStyleValueCircle = document.querySelectorAll(\".circleOutlineStyle\");\n\nclass Circle {\n constructor(x, y, rx, ry, options = {}) {\n this.x = x; \n this.y = y; \n this.rx = rx; \n this.ry = ry; \n this.options = {\n roughness: 1.5,\n stroke: \"#fff\",\n strokeWidth: 2,\n fill: \"transparent\",\n fillStyle: \"none\",\n strokeDasharray: \"\",\n ...options\n };\n // RoughJS otherwise generates a different contour on every redraw.\n // Keep a stable contour for later edits and the final drawing render.\n if (!Number.isInteger(this.options.seed) || this.options.seed <= 0) {\n this.options.seed = Math.floor(Math.random() * 0x7fffffff) + 1;\n }\n this.element = null;\n this.isSelected = false;\n this.rotation = 0;\n this.group = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n this.anchors = [];\n this.rotationAnchor = null;\n this.selectionPadding = 8;\n this.selectionOutline = null;\n this.shapeName = \"circle\";\n this.shapeID = `circle-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 10000)}`;\n this.group.setAttribute('id', this.shapeID);\n\n // Frame attachment properties\n this.parentFrame = null;\n\n // Embedded label support\n this.label = options.label || '';\n this.labelElement = null;\n this.labelColor = resolveThemeLabelColor(options.labelColor);\n this.labelFontSize = options.labelFontSize || DEFAULT_SHAPE_LABEL_FONT_SIZE;\n this._isEditingLabel = false;\n this._hitArea = null;\n this._labelBg = null;\n\n // Shading / gradient support for research paper style diagrams\n this.shadeColor = options.shadeColor || null;\n this.shadeOpacity = options.shadeOpacity !== undefined ? options.shadeOpacity : 0.15;\n this.shadeDirection = options.shadeDirection || 'bottom';\n this._shadeEllipse = null;\n this._shadeGradient = null;\n this.isBeingDrawn = false;\n this._drawingRenderFrame = null;\n this._isLivePreviewElement = false;\n\n if(!this.group.parentNode) {\n svg.appendChild(this.group);\n }\n this._lastDrawn = {\n width: null,\n height: null,\n options: null\n };\n this._setupLabelDblClick();\n this.draw();\n }\n\n // Add width and height properties for frame compatibility\n get width() {\n return this.rx * 2;\n }\n \n set width(value) {\n this.rx = value / 2;\n }\n \n get height() {\n return this.ry * 2;\n }\n \n set height(value) {\n this.ry = value / 2;\n }\n\n draw() {\n const childrenToRemove = [];\n const preserveSet = this._skipAnchors ? new Set([...this.anchors, this.selectionOutline, this.rotationAnchor].filter(Boolean)) : null;\n for (let i = 0; i < this.group.children.length; i++) {\n const child = this.group.children[i];\n if (child !== this.element && child !== this.labelElement && child !== this._hitArea && child !== this._labelBg && child !== this._shadeEllipse) {\n if (preserveSet && preserveSet.has(child)) continue;\n childrenToRemove.push(child);\n }\n }\n childrenToRemove.forEach(child => this.group.removeChild(child));\n const optionsString = JSON.stringify(this.options);\n const isInitialDraw = this.element === null;\n const sizeChanged = this.rx !== this._lastDrawn.rx || this.ry !== this._lastDrawn.ry;\n const optionsChanged = optionsString !== this._lastDrawn.options;\n if (this.isBeingDrawn) {\n if (!this._isLivePreviewElement) {\n if (this.element && this.element.parentNode === this.group) {\n this.group.removeChild(this.element);\n }\n this.element = document.createElementNS('http://www.w3.org/2000/svg', 'ellipse');\n this.element.setAttribute('class', 'circle-drawing-preview');\n this.element.setAttribute('pointer-events', 'none');\n this.group.appendChild(this.element);\n this._isLivePreviewElement = true;\n }\n\n this.element.setAttribute('cx', 0);\n this.element.setAttribute('cy', 0);\n this.element.setAttribute('rx', this.rx);\n this.element.setAttribute('ry', this.ry);\n this.element.setAttribute('fill', this.options.fill || 'transparent');\n this.element.setAttribute('stroke', this.options.stroke || '#fff');\n this.element.setAttribute('stroke-width', this.options.strokeWidth || 2);\n this.element.setAttribute('stroke-dasharray', this.options.strokeDasharray || '');\n } else if (isInitialDraw || optionsChanged || sizeChanged || this._isLivePreviewElement) {\n if (this.element && this.element.parentNode === this.group) {\n this.group.removeChild(this.element);\n }\n\n const roughEllipse = rc.ellipse(0, 0, this.rx * 2, this.ry * 2, this.options);\n this.element = roughEllipse;\n this.group.appendChild(roughEllipse);\n this._isLivePreviewElement = false;\n\n this._lastDrawn.rx = this.rx;\n this._lastDrawn.ry = this.ry;\n this._lastDrawn.options = optionsString;\n }\n\n // Hit area for dblclick detection\n if (!this._hitArea) {\n this._hitArea = document.createElementNS('http://www.w3.org/2000/svg', 'ellipse');\n this._hitArea.setAttribute('fill', 'transparent');\n this._hitArea.setAttribute('stroke', 'none');\n this._hitArea.setAttribute('style', 'pointer-events: all;');\n this.group.insertBefore(this._hitArea, this.group.firstChild);\n }\n this._hitArea.setAttribute('cx', 0);\n this._hitArea.setAttribute('cy', 0);\n this._hitArea.setAttribute('rx', this.rx);\n this._hitArea.setAttribute('ry', this.ry);\n\n // Shading / gradient overlay\n this._updateShade();\n\n // Update embedded label\n this._updateLabelElement();\n\n this.group.setAttribute('transform', `translate(${this.x}, ${this.y}) rotate(${this.rotation}, 0, 0)`);\n if (this.isSelected) {\n if (this._skipAnchors) {\n this.updateSelectionControls();\n } else {\n this.addAnchors();\n }\n }\n if (!this.group.parentNode) {\n svg.appendChild(this.group);\n }\n }\n\n scheduleDrawingRender() {\n if (this._drawingRenderFrame !== null) return;\n if (typeof requestAnimationFrame !== 'function') {\n this.draw();\n return;\n }\n this._drawingRenderFrame = requestAnimationFrame(() => {\n this._drawingRenderFrame = null;\n this.draw();\n });\n }\n\n cancelDrawingRender() {\n if (this._drawingRenderFrame !== null && typeof cancelAnimationFrame === 'function') {\n cancelAnimationFrame(this._drawingRenderFrame);\n }\n this._drawingRenderFrame = null;\n this.isBeingDrawn = false;\n }\n\n finalizeDrawing() {\n this.cancelDrawingRender();\n this.draw();\n }\n\n move(dx, dy) {\n this.x += dx;\n this.y += dy;\n\n // Fast path: just update the transform \u2014 no need to rebuild RoughJS element\n this.group.setAttribute('transform', `translate(${this.x}, ${this.y}) rotate(${this.rotation}, 0, 0)`);\n\n this.updateAttachedArrows();\n\n // Only update frame containment if we're actively dragging the shape itself\n // and not being moved by a parent frame\n if (isDraggingShapeCircle && !this.isBeingMovedByFrame) {\n this.updateFrameContainment();\n }\n }\n\n updateFrameContainment() {\n // Don't update if we're being moved by a frame\n if (this.isBeingMovedByFrame) return;\n \n let targetFrame = null;\n \n // Find which frame this shape is over\n shapes.forEach(shape => {\n if (shape.shapeName === 'frame' && shape.isShapeInFrame(this)) {\n targetFrame = shape;\n }\n });\n \n // If we have a parent frame and we're being dragged, temporarily remove clipping\n if (this.parentFrame && isDraggingShapeCircle) {\n this.parentFrame.temporarilyRemoveFromFrame(this);\n }\n \n // Update frame highlighting\n if (hoveredFrameCircle && hoveredFrameCircle !== targetFrame) {\n hoveredFrameCircle.removeHighlight();\n }\n \n if (targetFrame && targetFrame !== hoveredFrameCircle) {\n targetFrame.highlightFrame();\n }\n \n hoveredFrameCircle = targetFrame;\n }\n\n getRotatedCursor(direction, angle) {\n const directions = ['ns', 'nesw', 'ew', 'nwse'];\n angle = angle % 360;\n if (angle < 0) angle += 360;\n\n const baseDirectionMap = {\n '0': 'nwse', '1': 'nesw', \n '2': 'nesw', '3': 'nwse', \n '4': 'ns', '5': 'ns', \n '6': 'ew', '7': 'ew' \n };\n const baseDirection = baseDirectionMap[direction];\n let effectiveAngle = angle; \n if (baseDirection === 'nesw') {\n effectiveAngle += 45;\n } else if (baseDirection === 'ew') {\n effectiveAngle += 90;\n } else if (baseDirection === 'nwse') {\n effectiveAngle += 135;\n }\n effectiveAngle = effectiveAngle % 360;\n if (effectiveAngle < 0) effectiveAngle += 360;\n const index = Math.round(effectiveAngle / 45) % 4; \n let finalIndex;\n if (effectiveAngle >= 337.5 || effectiveAngle < 22.5) finalIndex = 0; \n else if (effectiveAngle >= 22.5 && effectiveAngle < 67.5) finalIndex = 1; \n else if (effectiveAngle >= 67.5 && effectiveAngle < 112.5) finalIndex = 2; \n else if (effectiveAngle >= 112.5 && effectiveAngle < 157.5) finalIndex = 3;\n else if (effectiveAngle >= 157.5 && effectiveAngle < 202.5) finalIndex = 0; \n else if (effectiveAngle >= 202.5 && effectiveAngle < 247.5) finalIndex = 1; \n else if (effectiveAngle >= 247.5 && effectiveAngle < 292.5) finalIndex = 2; \n else if (effectiveAngle >= 292.5 && effectiveAngle < 337.5) finalIndex = 3; \n else finalIndex = 0; \n return directions[finalIndex];\n }\n addAnchors() {\n const zoom = window.currentZoom || 1;\n const anchorSize = 10 / zoom;\n const anchorStrokeWidth = 2;\n const self = this;\n const expandedX = -this.rx - this.selectionPadding;\n const expandedY = -this.ry - this.selectionPadding; \n const expandedWidth = this.rx * 2 + 2 * this.selectionPadding;\n const expandedHeight = this.ry * 2 + 2 * this.selectionPadding;\n\n const positions = [\n { x: expandedX, y: expandedY }, \n { x: expandedX + expandedWidth, y: expandedY }, \n { x: expandedX, y: expandedY + expandedHeight }, \n { x: expandedX + expandedWidth, y: expandedY + expandedHeight }, \n { x: expandedX + expandedWidth / 2, y: expandedY }, \n { x: expandedX + expandedWidth / 2, y: expandedY + expandedHeight }, \n { x: expandedX, y: expandedHeight / 2 + expandedY }, \n { x: expandedX + expandedWidth, y: expandedHeight / 2 + expandedY } \n ];\n\n const outlinePoints = [\n [positions[0].x, positions[0].y],\n [positions[1].x, positions[1].y],\n [positions[3].x, positions[3].y],\n [positions[2].x, positions[2].y],\n [positions[0].x, positions[0].y]\n ];\n\n this.anchors.forEach(anchor => {\n if (anchor.parentNode === this.group) {\n this.group.removeChild(anchor);\n }\n });\n if (this.rotationAnchor && this.rotationAnchor.parentNode === this.group) {\n this.group.removeChild(this.rotationAnchor);\n }\n if (this.selectionOutline && this.selectionOutline.parentNode === this.group) {\n this.group.removeChild(this.selectionOutline);\n }\n\n this.anchors = [];\n const anchorDirections = {\n 0: 'nwse', \n 1: 'nesw', \n 2: 'nesw', \n 3: 'nwse', \n 4: 'ns', \n 5: 'ns', \n 6: 'ew', \n 7: 'ew' \n };\n\n positions.forEach((pos, i) => {\n const anchor = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n anchor.setAttribute('x', pos.x - anchorSize / 2);\n anchor.setAttribute('y', pos.y - anchorSize / 2);\n anchor.setAttribute('width', anchorSize);\n anchor.setAttribute('height', anchorSize);\n anchor.setAttribute('class', 'anchor');\n anchor.setAttribute('data-index', i);\n anchor.setAttribute('fill', '#121212');\n anchor.setAttribute('stroke', '#5B57D1');\n anchor.setAttribute('stroke-width', anchorStrokeWidth);\n anchor.setAttribute('vector-effect', 'non-scaling-stroke');\n anchor.setAttribute('style', 'pointer-events: all;');\n\n anchor.addEventListener('mouseover', function () {\n const index = this.getAttribute('data-index');\n const baseDirection = anchorDirections[index];\n const rotatedCursor = self.getRotatedCursor(index, self.rotation); \n svg.style.cursor = rotatedCursor + '-resize';\n });\n\n anchor.addEventListener('mouseout', function () {\n if (!isResizingShapeCircle && !isDraggingShapeCircle && !isRotatingShapeCircle) {\n svg.style.cursor = 'default';\n }\n });\n\n this.group.appendChild(anchor);\n this.anchors[i] = anchor;\n });\n const rotationAnchorPos = { x: expandedX + expandedWidth / 2, y: expandedY - 30 / zoom };\n this.rotationAnchor = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n this.rotationAnchor.setAttribute('cx', rotationAnchorPos.x);\n this.rotationAnchor.setAttribute('cy', rotationAnchorPos.y);\n this.rotationAnchor.setAttribute('r', 8 / zoom);\n this.rotationAnchor.setAttribute('class', 'rotate-anchor');\n this.rotationAnchor.setAttribute('fill', '#121212');\n this.rotationAnchor.setAttribute('stroke', '#5B57D1');\n this.rotationAnchor.setAttribute('stroke-width', anchorStrokeWidth);\n this.rotationAnchor.setAttribute('vector-effect', 'non-scaling-stroke');\n this.rotationAnchor.setAttribute('style', 'pointer-events: all;');\n this.group.appendChild(this.rotationAnchor);\n registerRotationAnchor(this.rotationAnchor, { radius: 8, edgeY: expandedY });\n\n this.rotationAnchor.addEventListener('mouseover', function () {\n if (!isResizingShapeCircle && !isDraggingShapeCircle && !isRotatingShapeCircle) {\n svg.style.cursor = 'grab';\n }\n });\n this.rotationAnchor.addEventListener('mouseout', function () {\n if (!isResizingShapeCircle && !isDraggingShapeCircle && !isRotatingShapeCircle) {\n svg.style.cursor = 'default';\n }\n });\n\n const pointsAttr = outlinePoints.map(p => p.join(',')).join(' ');\n const outline = document.createElementNS('http://www.w3.org/2000/svg', 'polyline');\n outline.setAttribute('points', pointsAttr);\n outline.setAttribute('class', 'selection-outline');\n outline.setAttribute('fill', 'none');\n outline.setAttribute('stroke', '#5B57D1');\n outline.setAttribute('stroke-width', 1.5);\n outline.setAttribute('vector-effect', 'non-scaling-stroke');\n outline.setAttribute('stroke-dasharray', '4 2');\n outline.setAttribute('style', 'pointer-events: none;');\n this.group.appendChild(outline);\n this.selectionOutline = outline;\n\n disableAllSideBars();\n circleSideBar.classList.remove(\"hidden\");\n if (window.__showSidebarForShape) window.__showSidebarForShape('circle');\n this.updateSidebar();\n }\n\n updateSelectionControls() {\n if (!this.selectionOutline || this.anchors.length === 0) return;\n\n const zoom = window.currentZoom || 1;\n const anchorSize = 10 / zoom;\n const expandedX = -this.rx - this.selectionPadding;\n const expandedY = -this.ry - this.selectionPadding;\n const expandedWidth = this.rx * 2 + 2 * this.selectionPadding;\n const expandedHeight = this.ry * 2 + 2 * this.selectionPadding;\n\n const positions = [\n { x: expandedX, y: expandedY },\n { x: expandedX + expandedWidth, y: expandedY },\n { x: expandedX, y: expandedY + expandedHeight },\n { x: expandedX + expandedWidth, y: expandedY + expandedHeight },\n { x: expandedX + expandedWidth / 2, y: expandedY },\n { x: expandedX + expandedWidth / 2, y: expandedY + expandedHeight },\n { x: expandedX, y: expandedHeight / 2 + expandedY },\n { x: expandedX + expandedWidth, y: expandedHeight / 2 + expandedY }\n ];\n\n positions.forEach((pos, i) => {\n if (this.anchors[i]) {\n this.anchors[i].setAttribute('x', pos.x - anchorSize / 2);\n this.anchors[i].setAttribute('y', pos.y - anchorSize / 2);\n }\n });\n\n const outlinePoints = [\n [positions[0].x, positions[0].y],\n [positions[1].x, positions[1].y],\n [positions[3].x, positions[3].y],\n [positions[2].x, positions[2].y],\n [positions[0].x, positions[0].y]\n ];\n this.selectionOutline.setAttribute('points', outlinePoints.map(p => p.join(',')).join(' '));\n\n if (this.rotationAnchor) {\n this.rotationAnchor.setAttribute('cx', expandedX + expandedWidth / 2);\n this.rotationAnchor.setAttribute('cy', expandedY - 30 / zoom);\n }\n }\n\n removeSelection() {\n this.anchors.forEach(anchor => {\n if (anchor.parentNode === this.group) {\n this.group.removeChild(anchor);\n }\n });\n if (this.rotationAnchor && this.rotationAnchor.parentNode === this.group) {\n this.group.removeChild(this.rotationAnchor);\n }\n if (this.selectionOutline && this.selectionOutline.parentNode === this.group) {\n this.group.removeChild(this.selectionOutline);\n }\n this.anchors = [];\n this.rotationAnchor = null;\n this.selectionOutline = null;\n this.isSelected = false;\n }\n contains(x, y) {\n if (!this.element || !this.rx || !this.ry) return false;\n // Mouse coordinates are in canvas space; invert the circle's own\n // translation/rotation without mixing in the viewport CTM.\n const angle = -(this.rotation || 0) * Math.PI / 180;\n const translatedX = x - this.x;\n const translatedY = y - this.y;\n const dx = translatedX * Math.cos(angle) - translatedY * Math.sin(angle);\n const dy = translatedX * Math.sin(angle) + translatedY * Math.cos(angle);\n const rx = this.rx;\n const ry = this.ry;\n return ((dx * dx) / (rx * rx) + (dy * dy) / (ry * ry)) <= 1.05; \n }\n isNearAnchor(x, y) {\n if (!this.isSelected) return null;\n const zoom = window.currentZoom || 1;\n const buffer = 10 / zoom; // Scale buffer by zoom level\n const anchorSize = 10 / zoom; // Scale anchor size by zoom level\n const transform = { x: this.x, y: this.y, rotation: this.rotation, centerX: 0, centerY: 0 };\n\n // Iterate through anchors\n for (let i = 0; i < this.anchors.length; i++) {\n const anchor = this.anchors[i];\n const anchorLocalX = parseFloat(anchor.getAttribute('x')) + anchorSize / 2;\n const anchorLocalY = parseFloat(anchor.getAttribute('y')) + anchorSize / 2;\n const transformedPoint = localToCanvas({ x: anchorLocalX, y: anchorLocalY }, transform);\n \n const anchorLeft = transformedPoint.x - anchorSize/2 - buffer;\n const anchorRight = transformedPoint.x + anchorSize/2 + buffer;\n const anchorTop = transformedPoint.y - anchorSize/2 - buffer;\n const anchorBottom = transformedPoint.y + anchorSize/2 + buffer;\n \n if (x >= anchorLeft && x <= anchorRight && y >= anchorTop && y <= anchorBottom) {\n return { type: 'resize', index: i };\n }\n }\n\n // Check rotation anchor\n if (this.rotationAnchor) {\n const rotateAnchorLocalX = parseFloat(this.rotationAnchor.getAttribute('cx'));\n const rotateAnchorLocalY = parseFloat(this.rotationAnchor.getAttribute('cy'));\n const transformedPoint = localToCanvas({ x: rotateAnchorLocalX, y: rotateAnchorLocalY }, transform);\n \n const rotateAnchorRadius = parseFloat(this.rotationAnchor.getAttribute('r'));\n const distSq = (x - transformedPoint.x)**2 + (y - transformedPoint.y)**2;\n if (distSq <= (rotateAnchorRadius + buffer)**2) {\n return { type: 'rotate' };\n }\n }\n\n return null;\n }\n\n updatePosition(anchorIndex, newMouseX, newMouseY) {\n const transformedPoint = canvasToLocal(\n { x: newMouseX, y: newMouseY },\n { x: this.x, y: this.y, rotation: this.rotation, centerX: 0, centerY: 0 },\n );\n \n const dx = transformedPoint.x;\n const dy = transformedPoint.y;\n \n const MIN_RADIUS = 10;\n \n switch (anchorIndex) {\n case 0: // top-left\n case 1: // top-right\n case 2: // bottom-left\n case 3: // bottom-right\n this.rx = Math.max(Math.abs(dx), MIN_RADIUS);\n this.ry = Math.max(Math.abs(dy), MIN_RADIUS);\n break;\n \n case 4: // top-center\n case 5: // bottom-center\n this.ry = Math.max(Math.abs(dy), MIN_RADIUS);\n break;\n \n case 6: // left-center\n case 7: // right-center\n this.rx = Math.max(Math.abs(dx), MIN_RADIUS);\n break;\n }\n this.updateAttachedArrows();\n }\n updateAttachedArrows() {\n shapes.forEach(shape => {\n if (shape && shape.shapeName === 'arrow' && typeof shape.updateAttachments === 'function') {\n if ((shape.attachedToStart && shape.attachedToStart.shape === this) ||\n (shape.attachedToEnd && shape.attachedToEnd.shape === this)) {\n shape.updateAttachments();\n }\n }\n });\n }\n _updateShade() {\n if (!this.shadeColor) {\n if (this._shadeEllipse && this._shadeEllipse.parentNode === this.group) {\n this.group.removeChild(this._shadeEllipse);\n this._shadeEllipse = null;\n }\n if (this._shadeGradient && this._shadeGradient.parentNode) {\n this._shadeGradient.parentNode.removeChild(this._shadeGradient);\n this._shadeGradient = null;\n }\n return;\n }\n\n let defs = svg.querySelector('defs');\n if (!defs) {\n defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n svg.appendChild(defs);\n }\n\n const gradId = `shade-${this.shapeID}`;\n if (!this._shadeGradient) {\n this._shadeGradient = document.createElementNS('http://www.w3.org/2000/svg', 'radialGradient');\n this._shadeGradient.setAttribute('id', gradId);\n defs.appendChild(this._shadeGradient);\n }\n\n // Radial gradient for circles - center to edge fade\n this._shadeGradient.setAttribute('cx', '50%');\n this._shadeGradient.setAttribute('cy', '50%');\n this._shadeGradient.setAttribute('r', '50%');\n\n while (this._shadeGradient.firstChild) this._shadeGradient.removeChild(this._shadeGradient.firstChild);\n const stop1 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');\n stop1.setAttribute('offset', '0%');\n stop1.setAttribute('stop-color', this.shadeColor);\n stop1.setAttribute('stop-opacity', this.shadeOpacity);\n const stop2 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');\n stop2.setAttribute('offset', '100%');\n stop2.setAttribute('stop-color', this.shadeColor);\n stop2.setAttribute('stop-opacity', '0');\n this._shadeGradient.appendChild(stop1);\n this._shadeGradient.appendChild(stop2);\n\n if (!this._shadeEllipse) {\n this._shadeEllipse = document.createElementNS('http://www.w3.org/2000/svg', 'ellipse');\n this._shadeEllipse.setAttribute('pointer-events', 'none');\n }\n this._shadeEllipse.setAttribute('cx', 0);\n this._shadeEllipse.setAttribute('cy', 0);\n this._shadeEllipse.setAttribute('rx', this.rx);\n this._shadeEllipse.setAttribute('ry', this.ry);\n this._shadeEllipse.setAttribute('fill', `url(#${gradId})`);\n\n if (this._shadeEllipse.parentNode === this.group) this.group.removeChild(this._shadeEllipse);\n if (this.element && this.element.nextSibling) {\n this.group.insertBefore(this._shadeEllipse, this.element.nextSibling);\n } else {\n this.group.appendChild(this._shadeEllipse);\n }\n }\n\n _updateLabelElement() {\n if (!this.label) {\n if (this.labelElement && this.labelElement.parentNode === this.group) {\n this.group.removeChild(this.labelElement);\n this.labelElement = null;\n }\n if (this._labelBg && this._labelBg.parentNode === this.group) {\n this.group.removeChild(this._labelBg);\n this._labelBg = null;\n }\n return;\n }\n\n if (!this.labelElement) {\n this.labelElement = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n this.labelElement.setAttribute('class', 'shape-label');\n this.labelElement.setAttribute('pointer-events', 'none');\n }\n\n // Circle center is at (0, 0) in local coords\n this.labelElement.setAttribute('x', 0);\n this.labelElement.setAttribute('y', 0);\n this.labelElement.setAttribute('text-anchor', 'middle');\n this.labelElement.setAttribute('dominant-baseline', 'central');\n this.labelElement.setAttribute('fill', this.labelColor);\n this.labelElement.setAttribute('font-size', this.labelFontSize);\n this.labelElement.setAttribute('font-family', 'lixFont, sans-serif');\n this.labelElement.textContent = this.label;\n\n // Background padding rect behind text (like arrows have)\n const canvasBg = window.getComputedStyle(svg).backgroundColor || '#000';\n if (!this._labelBg) {\n this._labelBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n this._labelBg.setAttribute('pointer-events', 'none');\n }\n this._labelBg.setAttribute('fill', canvasBg);\n const hPadding = 6;\n const vPadding = 2;\n const charWidth = this.labelFontSize * 0.6;\n const bgW = this.label.length * charWidth + hPadding * 2;\n const bgH = this.labelFontSize + vPadding * 2;\n this._labelBg.setAttribute('x', -bgW / 2);\n this._labelBg.setAttribute('y', -bgH / 2);\n this._labelBg.setAttribute('width', bgW);\n this._labelBg.setAttribute('height', bgH);\n this._labelBg.setAttribute('rx', 3);\n\n // Re-append bg then text on top\n if (this._labelBg.parentNode === this.group) this.group.removeChild(this._labelBg);\n if (this.labelElement.parentNode === this.group) this.group.removeChild(this.labelElement);\n this.group.appendChild(this._labelBg);\n this.group.appendChild(this.labelElement);\n }\n\n _setupLabelDblClick() {\n this.group.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n e.preventDefault();\n this.startLabelEdit();\n });\n }\n\n startLabelEdit() {\n if (this._isEditingLabel) return;\n this._isEditingLabel = true;\n\n if (this.labelElement) {\n this.labelElement.setAttribute('visibility', 'hidden');\n }\n\n // Get shape's screen position via CTM\n const ctm = this.group.getScreenCTM();\n if (!ctm) { this._isEditingLabel = false; return; }\n\n // Map the ellipse bounding box to screen coords\n const pt1 = svg.createSVGPoint();\n pt1.x = -this.rx; pt1.y = -this.ry;\n const screenTL = pt1.matrixTransform(ctm);\n const pt2 = svg.createSVGPoint();\n pt2.x = this.rx; pt2.y = this.ry;\n const screenBR = pt2.matrixTransform(ctm);\n\n const screenW = Math.abs(screenBR.x - screenTL.x);\n const screenH = Math.abs(screenBR.y - screenTL.y);\n const screenX = Math.min(screenTL.x, screenBR.x);\n const screenY = Math.min(screenTL.y, screenBR.y);\n\n // Create HTML overlay\n const overlay = document.createElement('div');\n overlay.className = 'shape-label-editor';\n overlay.style.cssText = `\n position: fixed; z-index: 10000;\n left: ${screenX}px; top: ${screenY}px;\n width: ${screenW}px; height: ${screenH}px;\n display: flex; align-items: center; justify-content: center;\n pointer-events: auto;\n `;\n\n const canvasBg = window.getComputedStyle(svg).backgroundColor || '#000';\n const input = document.createElement('div');\n input.setAttribute('contenteditable', 'true');\n input.style.cssText = `\n max-width: ${screenW - 8}px; min-width: 30px; min-height: 20px;\n background: ${canvasBg}; border: none;\n outline: none; padding: 2px 6px;\n color: ${this.labelColor}; font-size: ${Math.max(12, this.labelFontSize * (screenW / Math.max(this.rx * 2, 1)))}px;\n font-family: lixFont, sans-serif; text-align: center;\n white-space: pre-wrap; word-break: break-word;\n cursor: text;\n `;\n if (this.label) {\n input.textContent = this.label;\n } else {\n input.innerHTML = ' ';\n }\n\n overlay.appendChild(input);\n document.body.appendChild(overlay);\n\n setTimeout(() => {\n input.focus();\n const sel = window.getSelection();\n const range = document.createRange();\n range.selectNodeContents(input);\n sel.removeAllRanges();\n sel.addRange(range);\n }, 10);\n\n const finishEdit = () => {\n const newText = input.textContent.trim().replace(/\\u00A0/g, '');\n this.label = newText;\n this._isEditingLabel = false;\n\n if (overlay.parentNode) overlay.parentNode.removeChild(overlay);\n if (this.labelElement) this.labelElement.setAttribute('visibility', 'visible');\n this.draw();\n };\n\n input.addEventListener('blur', finishEdit);\n input.addEventListener('keydown', (e) => {\n e.stopPropagation();\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); input.blur(); }\n if (e.key === 'Escape') { input.textContent = this.label; input.blur(); }\n });\n input.addEventListener('pointerdown', (e) => e.stopPropagation());\n input.addEventListener('pointermove', (e) => e.stopPropagation());\n input.addEventListener('pointerup', (e) => e.stopPropagation());\n }\n\n setLabel(text, color, fontSize) {\n this.label = text || '';\n if (color) this.labelColor = color;\n if (fontSize) this.labelFontSize = fontSize;\n this.draw();\n }\n\n rotate(angle) {\n angle = angle % 360;\n if (angle < 0) angle += 360;\n this.rotation = angle;\n }\n // No-op: React sidebar handles UI updates via Zustand store\n updateSidebar() {}\n\n}\n\nexport { Circle };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -7,10 +7,15 @@ import {
|
|
|
7
7
|
getTargetedElements,
|
|
8
8
|
setIsErasing,
|
|
9
9
|
updateEraserTrail
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-PK7MU63Q.js";
|
|
11
11
|
|
|
12
12
|
// src/tools/eraserTool.js
|
|
13
|
-
|
|
13
|
+
function getEraserCursorSVG() {
|
|
14
|
+
const isLight = document.documentElement.dataset.canvasTheme === "light" || document.body?.classList.contains("theme-light");
|
|
15
|
+
const fill = isLight ? "#31283f" : "#f5effb";
|
|
16
|
+
const stroke = isLight ? "#ffffff" : "#31283f";
|
|
17
|
+
return `data:image/svg+xml;base64,${btoa(`<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><circle cx="10" cy="10" r="7" fill="${fill}" stroke="${stroke}" stroke-width="2"/></svg>`)}`;
|
|
18
|
+
}
|
|
14
19
|
window.forceCleanupEraserTrail = forceCleanupEraserTrail;
|
|
15
20
|
function findTopLevelGroup(element) {
|
|
16
21
|
if (!element || element === svg) return null;
|
|
@@ -80,10 +85,11 @@ svg.addEventListener("pointerdown", (e) => {
|
|
|
80
85
|
});
|
|
81
86
|
svg.addEventListener("pointermove", (e) => {
|
|
82
87
|
if (isEraserToolActive) {
|
|
83
|
-
svg.style.cursor = `url(${
|
|
88
|
+
svg.style.cursor = `url(${getEraserCursorSVG()}) 10 10, auto`;
|
|
84
89
|
}
|
|
85
90
|
if (!getIsErasing()) return;
|
|
86
|
-
|
|
91
|
+
const events = typeof e.getCoalescedEvents === "function" ? e.getCoalescedEvents() : [e];
|
|
92
|
+
events.forEach((point) => updateEraserTrail(point.clientX, point.clientY));
|
|
87
93
|
handleElementHighlight(e.clientX, e.clientY);
|
|
88
94
|
});
|
|
89
95
|
svg.addEventListener("pointerup", () => {
|
|
@@ -100,4 +106,4 @@ svg.addEventListener("pointerleave", (e) => {
|
|
|
100
106
|
fadeOutEraserTrail();
|
|
101
107
|
svg.style.cursor = "default";
|
|
102
108
|
});
|
|
103
|
-
//# sourceMappingURL=eraserTool-
|
|
109
|
+
//# sourceMappingURL=eraserTool-P6WR35AE.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/tools/eraserTool.js"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable */\n// Eraser tool - extracted from eraserTool.js\n// Depends on globals: svg, isEraserToolActive, ACTION_DELETE, historyStack, redoStack, clearAllSelections\nimport { createEraserTrail, updateEraserTrail, fadeOutEraserTrail, forceCleanupEraserTrail, getIsErasing, setIsErasing, getTargetedElements } from '../core/EraserTrail.js';\n\nfunction getEraserCursorSVG() {\n const isLight = document.documentElement.dataset.canvasTheme === 'light' || document.body?.classList.contains('theme-light');\n const fill = isLight ? '#31283f' : '#f5effb';\n const stroke = isLight ? '#ffffff' : '#31283f';\n return `data:image/svg+xml;base64,${btoa(`<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"><circle cx=\"10\" cy=\"10\" r=\"7\" fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"2\"/></svg>`)}`;\n}\n\n// Expose force cleanup on window so SketchEngine can call it on tool switch\nwindow.forceCleanupEraserTrail = forceCleanupEraserTrail;\n\n// Walk up from any element to find its top-level SVG child (direct child of svg)\nfunction findTopLevelGroup(element) {\n if (!element || element === svg) return null;\n let current = element;\n while (current && current.parentNode !== svg) {\n current = current.parentNode;\n if (!current || current === document.body) return null;\n }\n return current;\n}\n\n// --- Function to highlight elements under the eraser ---\nfunction handleElementHighlight(clientX, clientY) {\n if (!getIsErasing()) return;\n const targetedElements = getTargetedElements();\n\n const element = document.elementFromPoint(clientX, clientY);\n if (!element || element === svg) return;\n\n // Find the top-level SVG child group for this element\n let elementToHighlight = findTopLevelGroup(element);\n\n // Skip the eraser trail paths and any pointer-events:none elements\n if (!elementToHighlight) return;\n if (elementToHighlight.style.pointerEvents === 'none') return;\n\n if (!targetedElements.has(elementToHighlight)) {\n targetedElements.add(elementToHighlight);\n elementToHighlight.setAttribute(\"data-original-opacity\", elementToHighlight.style.opacity || \"1\");\n elementToHighlight.dataset.storedOpacity = elementToHighlight.getAttribute(\"data-original-opacity\");\n elementToHighlight.style.opacity = \"0.3\";\n }\n}\n\nfunction removeHighlight() {\n const targetedElements = getTargetedElements();\n targetedElements.forEach(element => {\n element.style.opacity = element.getAttribute(\"data-original-opacity\") || \"1\";\n });\n targetedElements.clear();\n}\n\nfunction removeTargetedElements() {\n const targetedElements = getTargetedElements();\n const elementsToRemove = Array.from(targetedElements);\n\n if (elementsToRemove.length > 0) {\n const deletionActions = [];\n\n elementsToRemove.forEach(element => {\n const originalOpacity = element.dataset.storedOpacity || \"1\";\n deletionActions.push({\n type: ACTION_DELETE,\n element: element,\n parent: element.parentNode,\n nextSibling: element.nextSibling,\n originalOpacity: originalOpacity,\n });\n\n // Remove from DOM\n if (element.parentNode) {\n element.parentNode.removeChild(element);\n }\n\n // Also remove from the global shapes array\n if (window.shapes) {\n const idx = window.shapes.findIndex(s =>\n s.element === element ||\n s.group === element ||\n s.wrapper === element\n );\n if (idx !== -1) {\n window.shapes.splice(idx, 1);\n }\n }\n });\n\n if (deletionActions.length > 0 && window.historyStack) {\n window.historyStack.push(...deletionActions);\n }\n\n window.redoStack = [];\n if (typeof clearAllSelections === 'function') clearAllSelections();\n if (typeof updateUndoRedoButtons === 'function') updateUndoRedoButtons();\n targetedElements.clear();\n }\n}\n\n// --- Event Listeners ---\nsvg.addEventListener(\"pointerdown\", (e) => {\n if (isEraserToolActive) {\n setIsErasing(true);\n createEraserTrail(e.clientX, e.clientY);\n handleElementHighlight(e.clientX, e.clientY);\n }\n});\n\nsvg.addEventListener(\"pointermove\", (e) => {\n if (isEraserToolActive) {\n svg.style.cursor = `url(${getEraserCursorSVG()}) 10 10, auto`;\n }\n if (!getIsErasing()) return;\n const events = typeof e.getCoalescedEvents === 'function' ? e.getCoalescedEvents() : [e];\n events.forEach((point) => updateEraserTrail(point.clientX, point.clientY));\n handleElementHighlight(e.clientX, e.clientY);\n});\n\nsvg.addEventListener(\"pointerup\", () => {\n if (!getIsErasing()) return;\n setIsErasing(false);\n removeTargetedElements();\n fadeOutEraserTrail();\n svg.style.cursor = \"default\";\n});\n\nsvg.addEventListener(\"pointerleave\", (e) => {\n if (!getIsErasing()) return;\n setIsErasing(false);\n removeTargetedElements();\n fadeOutEraserTrail();\n svg.style.cursor = \"default\";\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/react/index.js
CHANGED
|
@@ -159,7 +159,11 @@ var useSketchStore = create((set, get) => ({
|
|
|
159
159
|
getCursor: () => {
|
|
160
160
|
const tool = get().activeTool;
|
|
161
161
|
if (tool === TOOLS.ERASER) {
|
|
162
|
-
|
|
162
|
+
const isLight = typeof document !== "undefined" && document.documentElement.dataset.canvasTheme === "light";
|
|
163
|
+
const fill = isLight ? "#31283f" : "#f5effb";
|
|
164
|
+
const stroke = isLight ? "#ffffff" : "#31283f";
|
|
165
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><circle cx="10" cy="10" r="7" fill="${fill}" stroke="${stroke}" stroke-width="2"/></svg>`;
|
|
166
|
+
return `url("data:image/svg+xml;base64,${typeof btoa !== "undefined" ? btoa(svg) : ""}") 10 10, auto`;
|
|
163
167
|
}
|
|
164
168
|
if (tool === TOOLS.LASER) {
|
|
165
169
|
return `url("data:image/svg+xml;base64,${typeof btoa !== "undefined" ? btoa('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#1971c2" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>') : ""}") 0 0, auto`;
|
|
@@ -641,7 +645,7 @@ function useSketchEngine(svgRef, ready = true) {
|
|
|
641
645
|
setZoom: (zoom) => useSketchStore_default.setState({ zoom }),
|
|
642
646
|
getState: () => useSketchStore_default.getState()
|
|
643
647
|
};
|
|
644
|
-
const { SketchEngine } = await import("./SketchEngine-
|
|
648
|
+
const { SketchEngine } = await import("./SketchEngine-6UBUCW5L.js");
|
|
645
649
|
if (cancelled) return;
|
|
646
650
|
const engine = new SketchEngine(svgRef.current);
|
|
647
651
|
await engine.init();
|
|
@@ -1816,14 +1820,32 @@ function AppMenu() {
|
|
|
1816
1820
|
|
|
1817
1821
|
// src/react/components/sidebars/ShapeSidebar.jsx
|
|
1818
1822
|
import { useState as useState5, useRef as useRef5, useEffect as useEffect6 } from "react";
|
|
1823
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
1819
1824
|
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1820
1825
|
function ToolbarButton({ icon, preview, children, tooltip, label = tooltip }) {
|
|
1821
1826
|
const [open, setOpen] = useState5(false);
|
|
1822
1827
|
const ref = useRef5(null);
|
|
1828
|
+
const panelRef = useRef5(null);
|
|
1829
|
+
const [panelPosition, setPanelPosition] = useState5(null);
|
|
1830
|
+
useEffect6(() => {
|
|
1831
|
+
if (!open) return;
|
|
1832
|
+
const updatePosition = () => {
|
|
1833
|
+
const rect = ref.current?.getBoundingClientRect();
|
|
1834
|
+
if (!rect) return;
|
|
1835
|
+
setPanelPosition({ left: rect.left + rect.width / 2, top: rect.top - 12 });
|
|
1836
|
+
};
|
|
1837
|
+
updatePosition();
|
|
1838
|
+
window.addEventListener("resize", updatePosition);
|
|
1839
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
1840
|
+
return () => {
|
|
1841
|
+
window.removeEventListener("resize", updatePosition);
|
|
1842
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
1843
|
+
};
|
|
1844
|
+
}, [open]);
|
|
1823
1845
|
useEffect6(() => {
|
|
1824
1846
|
if (!open) return;
|
|
1825
1847
|
const handler = (e) => {
|
|
1826
|
-
if (ref.current && !
|
|
1848
|
+
if (!ref.current?.contains(e.target) && !panelRef.current?.contains(e.target)) setOpen(false);
|
|
1827
1849
|
};
|
|
1828
1850
|
document.addEventListener("mousedown", handler);
|
|
1829
1851
|
return () => document.removeEventListener("mousedown", handler);
|
|
@@ -1845,10 +1867,21 @@ function ToolbarButton({ icon, preview, children, tooltip, label = tooltip }) {
|
|
|
1845
1867
|
]
|
|
1846
1868
|
}
|
|
1847
1869
|
),
|
|
1848
|
-
open &&
|
|
1849
|
-
/* @__PURE__ */
|
|
1850
|
-
|
|
1851
|
-
|
|
1870
|
+
open && panelPosition && createPortal2(
|
|
1871
|
+
/* @__PURE__ */ jsxs6(
|
|
1872
|
+
"div",
|
|
1873
|
+
{
|
|
1874
|
+
ref: panelRef,
|
|
1875
|
+
className: "fixed -translate-x-1/2 -translate-y-full z-[10050] max-w-[calc(100vw-16px)]",
|
|
1876
|
+
style: panelPosition,
|
|
1877
|
+
children: [
|
|
1878
|
+
/* @__PURE__ */ jsx6("div", { className: "bg-surface-card border border-border-light rounded-xl p-3 shadow-xl shadow-black/10 min-w-max", children }),
|
|
1879
|
+
/* @__PURE__ */ jsx6("div", { className: "absolute -bottom-[5px] left-1/2 -translate-x-1/2 w-2.5 h-2.5 rotate-45 bg-surface-card border-r border-b border-border-light" })
|
|
1880
|
+
]
|
|
1881
|
+
}
|
|
1882
|
+
),
|
|
1883
|
+
document.body
|
|
1884
|
+
)
|
|
1852
1885
|
] });
|
|
1853
1886
|
}
|
|
1854
1887
|
function Divider() {
|
|
@@ -5111,7 +5144,7 @@ var _saveScene = null;
|
|
|
5111
5144
|
var _loadScene = null;
|
|
5112
5145
|
async function ensureSceneSerializer() {
|
|
5113
5146
|
if (_saveScene && _loadScene) return;
|
|
5114
|
-
const m = await import("./SceneSerializer-
|
|
5147
|
+
const m = await import("./SceneSerializer-X5GJFI2E.js");
|
|
5115
5148
|
_saveScene = m.saveScene;
|
|
5116
5149
|
_loadScene = m.loadScene;
|
|
5117
5150
|
}
|