test
This commit is contained in:
1
dist/assets/index-DDld2teB.css
vendored
Normal file
1
dist/assets/index-DDld2teB.css
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.canvas-container{position:fixed;top:0;right:0;bottom:0;left:0;overflow:hidden;cursor:default;background:var(--bg);touch-action:none;overscroll-behavior:contain}.canvas-container.pan-mode{cursor:grab}.canvas-container.panning{cursor:grabbing}.canvas-grid{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;background-image:radial-gradient(circle,var(--bg-grid) 1px,transparent 1px);background-repeat:repeat}.canvas-world{position:absolute;top:0;left:0;width:0;height:0;transform-origin:0 0}.canvas-hud{position:fixed;bottom:12px;left:12px;display:flex;gap:12px;padding:6px 10px;background:#00000080;border-radius:6px;font-size:11px;font-family:ui-monospace,Menlo,monospace;color:var(--text);pointer-events:none}.card{position:absolute;background:var(--card-bg);border:1px solid var(--card-border);border-radius:8px;box-shadow:0 4px 16px #0000004d;overflow:hidden;display:flex;flex-direction:column}.card-header{padding:6px 10px;background:#0003;border-bottom:1px solid var(--card-border);font-size:11px;cursor:move;flex-shrink:0}.card-body{flex:1;overflow:auto}.note-card textarea{width:100%;height:100%;background:transparent;border:none;outline:none;resize:none;color:var(--text);font-family:inherit;font-size:13px;padding:10px}:root{--bg: #1a1a1f;--bg-grid: #25252c;--card-bg: #2a2a32;--card-border: #3a3a45;--text: #e8e8ec;--accent: #6a8cff;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color-scheme:dark}*{box-sizing:border-box;margin:0;padding:0}html,body,#root{width:100%;height:100%;overflow:hidden;background:var(--bg);color:var(--text);-webkit-user-select:none;user-select:none}
|
||||||
File diff suppressed because one or more lines are too long
1
dist/assets/index-DuETBnoW.css
vendored
1
dist/assets/index-DuETBnoW.css
vendored
@@ -1 +0,0 @@
|
|||||||
.canvas-container{position:fixed;top:0;right:0;bottom:0;left:0;overflow:hidden;cursor:default;background:var(--bg)}.canvas-container.pan-mode{cursor:grab}.canvas-grid{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;background-image:radial-gradient(circle,var(--bg-grid) 1px,transparent 1px);background-repeat:repeat}.canvas-world{position:absolute;top:0;left:0;width:0;height:0;transform-origin:0 0}.canvas-hud{position:fixed;bottom:12px;left:12px;display:flex;gap:12px;padding:6px 10px;background:#00000080;border-radius:6px;font-size:11px;font-family:ui-monospace,Menlo,monospace;color:var(--text);pointer-events:none}.card{position:absolute;background:var(--card-bg);border:1px solid var(--card-border);border-radius:8px;box-shadow:0 4px 16px #0000004d;overflow:hidden;display:flex;flex-direction:column}.card-header{padding:6px 10px;background:#0003;border-bottom:1px solid var(--card-border);font-size:11px;cursor:move;flex-shrink:0}.card-body{flex:1;overflow:auto}.note-card textarea{width:100%;height:100%;background:transparent;border:none;outline:none;resize:none;color:var(--text);font-family:inherit;font-size:13px;padding:10px}:root{--bg: #1a1a1f;--bg-grid: #25252c;--card-bg: #2a2a32;--card-border: #3a3a45;--text: #e8e8ec;--accent: #6a8cff;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color-scheme:dark}*{box-sizing:border-box;margin:0;padding:0}html,body,#root{width:100%;height:100%;overflow:hidden;background:var(--bg);color:var(--text);-webkit-user-select:none;user-select:none}
|
|
||||||
4
dist/index.html
vendored
4
dist/index.html
vendored
@@ -4,8 +4,8 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Infinite</title>
|
<title>Infinite</title>
|
||||||
<script type="module" crossorigin src="/assets/index-CurFfSxZ.js"></script>
|
<script type="module" crossorigin src="/assets/index-DYmGrN0R.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-DuETBnoW.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-DDld2teB.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@@ -35,8 +35,27 @@ export function Canvas({ initialCards }: CanvasProps) {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onWheel = useCallback(
|
// Suppress WebKit/GTK middle-click defaults (autoscroll on some platforms,
|
||||||
(e: React.WheelEvent) => {
|
// paste primary selection on Linux). Must be a native listener — React's
|
||||||
|
// synthetic onPointerDown.preventDefault doesn't reliably stop these.
|
||||||
|
useEffect(() => {
|
||||||
|
const el = containerRef.current;
|
||||||
|
if (!el) return;
|
||||||
|
const stopMiddle = (e: MouseEvent) => {
|
||||||
|
if (e.button === 1) e.preventDefault();
|
||||||
|
};
|
||||||
|
const stopAux = (e: MouseEvent) => {
|
||||||
|
if (e.button === 1) e.preventDefault();
|
||||||
|
};
|
||||||
|
el.addEventListener("mousedown", stopMiddle);
|
||||||
|
el.addEventListener("auxclick", stopAux);
|
||||||
|
return () => {
|
||||||
|
el.removeEventListener("mousedown", stopMiddle);
|
||||||
|
el.removeEventListener("auxclick", stopAux);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onWheel = useCallback((e: React.WheelEvent) => {
|
||||||
if (!e.ctrlKey && !e.metaKey) return;
|
if (!e.ctrlKey && !e.metaKey) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const rect = containerRef.current!.getBoundingClientRect();
|
const rect = containerRef.current!.getBoundingClientRect();
|
||||||
@@ -48,15 +67,15 @@ export function Canvas({ initialCards }: CanvasProps) {
|
|||||||
const k = next / prev.scale;
|
const k = next / prev.scale;
|
||||||
return { x: mx - (mx - prev.x) * k, y: my - (my - prev.y) * k, scale: next };
|
return { x: mx - (mx - prev.x) * k, y: my - (my - prev.y) * k, scale: next };
|
||||||
});
|
});
|
||||||
},
|
}, []);
|
||||||
[],
|
|
||||||
);
|
|
||||||
|
|
||||||
const onPointerDown = (e: React.PointerEvent) => {
|
const onPointerDown = (e: React.PointerEvent) => {
|
||||||
const isPan = e.button === 1 || (e.button === 0 && spaceHeld);
|
const isPan = e.button === 1 || (e.button === 0 && spaceHeld);
|
||||||
if (!isPan) return;
|
if (!isPan) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
(e.target as Element).setPointerCapture(e.pointerId);
|
// Capture on the container, not e.target — survives card re-renders and
|
||||||
|
// avoids odd behavior when the click lands on a textarea or child element.
|
||||||
|
containerRef.current?.setPointerCapture(e.pointerId);
|
||||||
panState.current = { startX: e.clientX, startY: e.clientY, vpX: vp.x, vpY: vp.y };
|
panState.current = { startX: e.clientX, startY: e.clientY, vpX: vp.x, vpY: vp.y };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,7 +88,11 @@ export function Canvas({ initialCards }: CanvasProps) {
|
|||||||
|
|
||||||
const onPointerUp = (e: React.PointerEvent) => {
|
const onPointerUp = (e: React.PointerEvent) => {
|
||||||
if (panState.current) {
|
if (panState.current) {
|
||||||
(e.target as Element).releasePointerCapture(e.pointerId);
|
try {
|
||||||
|
containerRef.current?.releasePointerCapture(e.pointerId);
|
||||||
|
} catch {
|
||||||
|
// capture may already be released if pointercancel fired
|
||||||
|
}
|
||||||
panState.current = null;
|
panState.current = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -81,7 +104,7 @@ export function Canvas({ initialCards }: CanvasProps) {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
className={`canvas-container ${spaceHeld ? "pan-mode" : ""}`}
|
className={`canvas-container ${spaceHeld ? "pan-mode" : ""} ${panState.current ? "panning" : ""}`}
|
||||||
onWheel={onWheel}
|
onWheel={onWheel}
|
||||||
onPointerDown={onPointerDown}
|
onPointerDown={onPointerDown}
|
||||||
onPointerMove={onPointerMove}
|
onPointerMove={onPointerMove}
|
||||||
|
|||||||
@@ -4,12 +4,18 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
|
touch-action: none;
|
||||||
|
overscroll-behavior: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.canvas-container.pan-mode {
|
.canvas-container.pan-mode {
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.canvas-container.panning {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
|
||||||
.canvas-grid {
|
.canvas-grid {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user