Skip to content
53 changes: 52 additions & 1 deletion site/src/components/ShapeBuilder/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// /* global window */
import React, { useEffect, useRef, useState } from "react";
import { Wrapper, CanvasContainer, OutputBox, StyledSVG, CopyButton } from "./shapeBuilder.styles";
import { Wrapper, CanvasContainer, OutputBox, StyledSVG, CopyButton, CoordinateDisplay } from "./shapeBuilder.styles";
import { Button, Typography, Box, CopyIcon } from "@sistent/sistent";
import { SVG, extend as SVGextend } from "@svgdotjs/svg.js";
import draw from "@svgdotjs/svg.draw.js";
Expand All @@ -15,6 +15,9 @@ const ShapeBuilder = () => {
const [error, setError] = useState(null);
const [showCopied, setShowCopied] = useState(false);

const [mouseCoords, setMouseCoords] = useState({ x: 0, y: 0, normalized: { x: 0, y: 0 } });
const [isMouseInCanvas, setIsMouseInCanvas] = useState(false);

const handleCopyToClipboard = async () => {
if (!result.trim()) return;

Expand Down Expand Up @@ -70,6 +73,39 @@ const ShapeBuilder = () => {
poly.move(0, 0);
showCytoArray();
};

const handleMouseMove = (e) => {
const svg = boardRef.current;
if (!svg) return;

const rect = svg.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const centerX = rect.width / 2;
const centerY = rect.height / 2;
const normalizedX = (x - centerX) / centerX;
const normalizedY = (y - centerY) / centerY;

setMouseCoords({
x: Math.round(x),
y: Math.round(y),
normalized: {
x: parseFloat(normalizedX.toFixed(3)),
y: parseFloat(normalizedY.toFixed(3))
},

screenX: e.clientX,
screenY: e.clientY
});
};

const handleMouseEnter = () => {
setIsMouseInCanvas(true);
};

const handleMouseLeave = () => {
setIsMouseInCanvas(false);
};

const handleKeyDown = (e) => {
const poly = polyRef.current;
Expand Down Expand Up @@ -177,6 +213,9 @@ const ShapeBuilder = () => {
width="100%"
height="100%"
onDoubleClick={closeShape}
onMouseMove={handleMouseMove}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<defs>
<pattern id="grid" width="16" height="16" patternUnits="userSpaceOnUse">
Expand All @@ -185,6 +224,18 @@ const ShapeBuilder = () => {
</defs>
<rect className="grid" width="100%" height="100%" fill="url(#grid)" />
</StyledSVG>

{isMouseInCanvas && (
<CoordinateDisplay
style={{
left: `${mouseCoords.x + 15}px`,
top: `${mouseCoords.y + 15}px`
}}
>
X: {mouseCoords.normalized.x}, Y: {mouseCoords.normalized.y}
</CoordinateDisplay>
)}

{error && (
<div style={{
position: "absolute",
Expand Down
18 changes: 18 additions & 0 deletions site/src/components/ShapeBuilder/shapeBuilder.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,24 @@ export const CopyButton = styled.button`
}
`;

export const CoordinateDisplay = styled.div`
position: absolute;
pointer-events: none;
background-color: ${({ theme }) => theme?.mode === "light" ? "rgba(255, 255, 255, 0.95)" : "rgba(43, 43, 43, 0.95)"};
border: 2px solid #00B39F;
border-radius: 6px;
padding: 6px 10px;
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
font-size: 12px;
font-weight: 600;
color: ${({ theme }) => theme?.mode === "light" ? "#111" : "#fff"};
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
z-index: 1000;
user-select: none;
white-space: nowrap;
transition: left 0.05s ease-out, top 0.05s ease-out;
`;

// export const Wrapper = styled.div`
// padding: 2rem;
// background-color: ${({ theme }) => theme.palette.background.default};
Expand Down