commit 1818e336e2cc2445cd1006f83c3fa66c7eec7259
parent 63a3d148e5733c645300c806f4ffdafd4d344f71
Author: Brian Graham <brian@buildingbetterteams.de>
Date: Sun, 22 Mar 2026 19:04:29 +0100
Fix network: edge contrast, mouseover hit detection
- Edge opacity 0.25 → 0.5, line width 0.8 → 1.2
- Fixed mouseover/click: canvas CSS scaling wasn't accounted for in
mouse coordinate math, making hit detection wildly off on any
screen where the canvas CSS width != 1200px (i.e. almost always)
- Zoom and drag also fixed for the same CSS-to-canvas scaling issue
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Diffstat:
2 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/explorer/src/style.css b/explorer/src/style.css
@@ -10,7 +10,7 @@
--red: #f06565;
--yellow: #f0c050;
--gray: #555;
- --net-edge: rgba(140, 170, 255, 0.25);
+ --net-edge: rgba(160, 190, 255, 0.5);
--net-bg: #1a1d27;
--grid-line: #2a2d3a;
--hover-bg: rgba(108, 140, 255, 0.08);
@@ -29,7 +29,7 @@
--red: #c93c3c;
--yellow: #b38a1a;
--gray: #999;
- --net-edge: rgba(60, 90, 200, 0.3);
+ --net-edge: rgba(80, 110, 200, 0.5);
--net-bg: #ffffff;
--grid-line: #e0e2e8;
--hover-bg: rgba(59, 92, 204, 0.06);
diff --git a/explorer/src/views/network.ts b/explorer/src/views/network.ts
@@ -150,7 +150,7 @@ export async function renderNetwork(app: HTMLElement) {
// Edges — visible on both themes
ctx.strokeStyle = getEdgeColor();
- ctx.lineWidth = 0.8;
+ ctx.lineWidth = 1.2;
for (const [si, ti] of simEdges) {
ctx.beginPath();
ctx.moveTo(simNodes[si].x, simNodes[si].y);
@@ -184,20 +184,35 @@ export async function renderNetwork(app: HTMLElement) {
dragMoved = false;
lastX = e.clientX; lastY = e.clientY;
});
+ // Convert mouse event to canvas-space coordinates (accounts for CSS scaling)
+ function canvasCoords(e: MouseEvent): { cx: number; cy: number } {
+ const rect = canvas.getBoundingClientRect();
+ const scaleX = canvas.width / rect.width;
+ const scaleY = canvas.height / rect.height;
+ return {
+ cx: (e.clientX - rect.left) * scaleX,
+ cy: (e.clientY - rect.top) * scaleY,
+ };
+ }
+
canvas.addEventListener('mousemove', e => {
if (dragging) {
const dx = e.clientX - lastX, dy = e.clientY - lastY;
if (Math.abs(dx) > 2 || Math.abs(dy) > 2) dragMoved = true;
- transform.x += dx;
- transform.y += dy;
+ // Scale drag delta to canvas space
+ const rect = canvas.getBoundingClientRect();
+ const scaleX = canvas.width / rect.width;
+ const scaleY = canvas.height / rect.height;
+ transform.x += dx * scaleX;
+ transform.y += dy * scaleY;
lastX = e.clientX; lastY = e.clientY;
draw();
}
- // Tooltip — larger hit radius
- const rect = canvas.getBoundingClientRect();
- const mx = (e.clientX - rect.left - transform.x) / transform.k;
- const my = (e.clientY - rect.top - transform.y) / transform.k;
+ // Tooltip — use canvas-space coordinates
+ const { cx, cy } = canvasCoords(e);
+ const mx = (cx - transform.x) / transform.k;
+ const my = (cy - transform.y) / transform.k;
let closest: SimNode | null = null;
let closestDist = 25;
@@ -225,20 +240,18 @@ export async function renderNetwork(app: HTMLElement) {
canvas.addEventListener('wheel', e => {
e.preventDefault();
const factor = e.deltaY > 0 ? 0.9 : 1.1;
- const rect = canvas.getBoundingClientRect();
- const mx = e.clientX - rect.left;
- const my = e.clientY - rect.top;
- transform.x = mx - (mx - transform.x) * factor;
- transform.y = my - (my - transform.y) * factor;
+ const { cx, cy } = canvasCoords(e);
+ transform.x = cx - (cx - transform.x) * factor;
+ transform.y = cy - (cy - transform.y) * factor;
transform.k *= factor;
draw();
}, { passive: false });
canvas.addEventListener('click', e => {
if (dragMoved) return; // don't navigate after a drag
- const rect = canvas.getBoundingClientRect();
- const mx = (e.clientX - rect.left - transform.x) / transform.k;
- const my = (e.clientY - rect.top - transform.y) / transform.k;
+ const { cx, cy } = canvasCoords(e);
+ const mx = (cx - transform.x) / transform.k;
+ const my = (cy - transform.y) / transform.k;
for (const n of simNodes) {
const d = Math.sqrt((n.x - mx) ** 2 + (n.y - my) ** 2);
if (d < 20 && n.has_scan) { navigate(`/paper/${n.id}`); return; }