diff --git a/lib/folk-comment-pin.ts b/lib/folk-comment-pin.ts index a172d60..aa88390 100644 --- a/lib/folk-comment-pin.ts +++ b/lib/folk-comment-pin.ts @@ -165,28 +165,29 @@ export class CommentPinManager { this.createPin(anchor); } - handleCanvasClick(worldX: number, worldY: number) { + handleCanvasClick(worldX: number, worldY: number, clientX?: number, clientY?: number) { if (!this.#placementMode) return false; - // Check if clicking on a shape - const shapeEl = document.elementFromPoint( - worldX * this.#scale + this.#panX, - worldY * this.#scale + this.#panY, - )?.closest?.("folk-shape, folk-markdown, folk-wrapper, folk-slide, folk-prompt, folk-zine-gen, folk-image-gen, folk-video-gen, folk-embed, folk-chat, folk-rapp") as HTMLElement | null; + // Check if clicking on a shape — elementFromPoint needs viewport coords + let shapeEl: HTMLElement | null = null; + if (clientX !== undefined && clientY !== undefined) { + shapeEl = document.elementFromPoint(clientX, clientY) + ?.closest?.("folk-shape, folk-markdown, folk-wrapper, folk-slide, folk-prompt, folk-zine-gen, folk-image-gen, folk-video-gen, folk-embed, folk-chat, folk-rapp") as HTMLElement | null; + } let anchor: CommentPinAnchor; if (shapeEl?.id) { - const shapeRect = shapeEl.getBoundingClientRect(); - const canvasRect = this.#container.getBoundingClientRect(); - // Offset relative to shape origin - const shapeWorldX = (shapeRect.left - canvasRect.left - this.#panX) / this.#scale; - const shapeWorldY = (shapeRect.top - canvasRect.top - this.#panY) / this.#scale; - anchor = { - type: "shape", - shapeId: shapeEl.id, - offsetX: worldX - shapeWorldX, - offsetY: worldY - shapeWorldY, - }; + const shapeData = this.#sync.doc.shapes?.[shapeEl.id]; + if (shapeData) { + anchor = { + type: "shape", + shapeId: shapeEl.id, + offsetX: worldX - shapeData.x, + offsetY: worldY - shapeData.y, + }; + } else { + anchor = { type: "canvas", offsetX: worldX, offsetY: worldY }; + } } else { anchor = { type: "canvas", offsetX: worldX, offsetY: worldY }; } diff --git a/website/canvas.html b/website/canvas.html index 309e610..5d5a959 100644 --- a/website/canvas.html +++ b/website/canvas.html @@ -4021,6 +4021,8 @@ } if (wbTool) setWbTool(null); if (pendingTool) clearPendingTool(); + if (typeof exitCommentMode === "function") exitCommentMode(); + pinManager.closePopover(); if (connectMode) { connectMode = false; canvas.classList.remove("connect-mode"); @@ -4667,6 +4669,7 @@ function toggleConnectMode() { if (wbTool) setWbTool(null); if (pendingTool) clearPendingTool(); + exitCommentMode(); connectMode = !connectMode; canvas.classList.toggle("connect-mode", connectMode); if (!connectMode && connectSource) { @@ -5153,6 +5156,7 @@ function setWbTool(tool) { wbTool = wbTool === tool ? null : tool; + if (typeof exitCommentMode === "function") exitCommentMode(); if (wbTool) { canvas.style.cursor = "crosshair"; @@ -5180,7 +5184,9 @@ function syncBottomToolbar() { bottomToolBtns.forEach(b => b.classList.remove("active")); - if (wbTool) { + if (pinManager?.placementMode) { + document.getElementById("tool-comment")?.classList.add("active"); + } else if (wbTool) { const map = { pencil: "tool-pencil", line: "tool-line", rect: "tool-rect", circle: "tool-circle", eraser: "tool-eraser" }; document.getElementById(map[wbTool])?.classList.add("active"); } else if (connectMode) { @@ -5202,6 +5208,7 @@ document.getElementById("tool-select").addEventListener("click", () => { if (wbTool) setWbTool(null); if (pendingTool) clearPendingTool(); + exitCommentMode(); if (connectMode) { connectMode = false; canvas.classList.remove("connect-mode"); @@ -5232,19 +5239,27 @@ }); // ── Comment tool ── - document.getElementById("tool-comment").addEventListener("click", () => { - if (pendingTool) clearPendingTool(); - setWbTool(null); + function exitCommentMode() { if (pinManager.placementMode) { pinManager.exitPinPlacementMode(); document.getElementById("tool-comment").classList.remove("active"); + } + } + document.getElementById("tool-comment").addEventListener("click", () => { + if (pendingTool) clearPendingTool(); + if (wbTool) setWbTool(null); + if (connectMode) { + connectMode = false; + canvas.classList.remove("connect-mode"); + if (connectSource) { connectSource.classList.remove("connect-source"); connectSource = null; } + } + if (pinManager.placementMode) { + exitCommentMode(); + syncBottomToolbar(); } else { pinManager.enterPinPlacementMode(); + bottomToolBtns.forEach(b => b.classList.remove("active")); document.getElementById("tool-comment").classList.add("active"); - // Deactivate other tools - document.querySelectorAll(".tool-btn").forEach(b => { - if (b.id !== "tool-comment") b.classList.remove("active"); - }); } }); @@ -5603,7 +5618,7 @@ const rect = canvas.getBoundingClientRect(); const worldX = (e.clientX - rect.left - panX) / scale; const worldY = (e.clientY - rect.top - panY) / scale; - pinManager.handleCanvasClick(worldX, worldY); + pinManager.handleCanvasClick(worldX, worldY, e.clientX, e.clientY); document.getElementById("tool-comment").classList.remove("active"); }, true);