mirror of
https://github.com/andwati/andwati.com.git
synced 2026-10-26 21:02:16 +00:00
Data model: nodes are real content entries (writings, portfolio, bookshelf), edges are shared-tag connections — the same relationship "related posts" already uses, drawn instead of listed. No decorative or fake data. - src/lib/constellation-data.ts: builds the node/edge graph from the actual collections at build time. - src/lib/constellation-scene.ts: vanilla Three.js scene (no framework) — fibonacci-sphere layout, auto-rotation, pointer raycasting with a title tooltip, click-through to the entry's page. Honors prefers-reduced-motion (skips rotation and the spring-eased entrance, which reuses src/lib/spring.ts) and checks WebGL support, falling back to a plain count for browsers/settings that lack it. - src/components/Constellation.astro: wires it up, serializing the graph as inline JSON for the client script to consume. - Homepage rebuilt around it: hero constellation above a 3-column dashboard (latest writings/portfolio/bookshelf), using a new `wide` layout variant on Base.astro (dashboard needs more than the 42rem article width). Also: removes "life and beliefs" from all site copy (site.config.ts, the llms.txt generator + its output) per request — description is now "Computer science and mathematics." Verified in-browser: real WebGL scene renders with correctly positioned/colored nodes and edges, hover shows the right title via raycasting, layout holds at the new wide container width.
71 lines
2.0 KiB
Plaintext
71 lines
2.0 KiB
Plaintext
---
|
|
import { buildConstellationGraph } from "../lib/constellation-data";
|
|
|
|
const graph = await buildConstellationGraph();
|
|
---
|
|
|
|
<div class="constellation" data-constellation>
|
|
<div class="constellation-canvas" data-canvas aria-hidden="true"></div>
|
|
<div class="constellation-tooltip" data-tooltip></div>
|
|
<noscript>
|
|
<p class="meta">
|
|
{graph.nodes.length} entries, connected by shared tags — enable JavaScript to explore the constellation.
|
|
</p>
|
|
</noscript>
|
|
</div>
|
|
|
|
<script type="application/json" id="constellation-data" is:inline set:html={JSON.stringify(graph)} />
|
|
|
|
<style>
|
|
.constellation {
|
|
position: relative;
|
|
width: 100%;
|
|
aspect-ratio: 16 / 9;
|
|
max-height: 60vh;
|
|
margin-bottom: var(--space-6);
|
|
}
|
|
.constellation-canvas {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
.constellation-canvas canvas {
|
|
display: block;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
.constellation-tooltip {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
pointer-events: none;
|
|
font-family: var(--font-mono);
|
|
font-size: var(--font-size-sm);
|
|
background: var(--bg-elevated);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
padding: var(--space-1) var(--space-3);
|
|
opacity: 0;
|
|
transition: opacity 0.15s var(--ease-out);
|
|
white-space: nowrap;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
import type { ConstellationGraph } from "../lib/constellation-data";
|
|
import { mountConstellation, supportsWebGL } from "../lib/constellation-scene";
|
|
|
|
const root = document.querySelector<HTMLElement>("[data-constellation]");
|
|
const canvas = root?.querySelector<HTMLElement>("[data-canvas]");
|
|
const tooltip = root?.querySelector<HTMLElement>("[data-tooltip]");
|
|
const dataEl = document.getElementById("constellation-data");
|
|
|
|
if (root && canvas && tooltip && dataEl?.textContent && supportsWebGL()) {
|
|
const graph: ConstellationGraph = JSON.parse(dataEl.textContent);
|
|
if (graph.nodes.length > 0) {
|
|
mountConstellation(canvas, tooltip, graph);
|
|
}
|
|
} else if (root) {
|
|
root.style.display = "none";
|
|
}
|
|
</script>
|