hero.js: alt modulen legger til, ligger i .hero-piece
lint-and-reload / lint (push) Successful in 2s

Canvaset lå først i selve headeren, lagt til før appen hydrerte, og
det kastet hydreringen av sporet: ingen ruter, hvert klikk en full
sideinnlasting. Nå ligger canvaset i piece-boksen som navnet, og
dekker headeren ved at fit() setter høyde og topp-forskyvning.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
blandClaude Fable 5.1 committed 2026-10-21 15:04:54 +02:00
1 parent 1f2f184d8f
commit f61e3d2d70
1 file changed
+17 -7
+17 -7
View File
@@ -207,11 +207,17 @@ const CSS = `
text-shadow: 0 0.12em 1.4em var(--hero-glow); text-shadow: 0 0.12em 1.4em var(--hero-glow);
} }
/* Behind everything in the header (the header is a stacking context /* The canvas lives in the piece (everything the module adds to the
of its own, so -1 is still above the page). */ page goes inside the piece: a node added anywhere else before the
app hydrates throws the hydration off, and with it client-side
navigation) but covers the whole header: fit() sets its height to
the header's box and its top to the piece's offset in it. Behind
everything in the header: the header is a stacking context of its
own, so -1 is still above the page. */
.westra-line { .westra-line {
position: absolute; position: absolute;
inset: 0; top: 0;
left: 0;
z-index: -1; z-index: -1;
width: 100%; width: 100%;
height: 100%; height: 100%;
@@ -338,10 +344,9 @@ class WestraHero {
mark.append(a, b); mark.append(a, b);
this.name.append(mark); this.name.append(mark);
this.mark = mark; this.mark = mark;
// The canvas covers the whole sticky header, under everything // Both inside the piece, and nothing outside it (see .westra-line).
// in it; the name sits in the piece, the space above the copy. this.container = container;
(this.hero || container).prepend(this.canvas); container.append(this.canvas, this.name);
container.append(this.name);
this.width = 0; this.width = 0;
this.height = 1; this.height = 1;
@@ -450,6 +455,11 @@ class WestraHero {
// is the fonts'. // is the fonts'.
fit() { fit() {
this.boxHeight = Math.max(1, this.hero ? this.hero.offsetHeight : this.height); this.boxHeight = Math.max(1, this.hero ? this.hero.offsetHeight : this.height);
if (this.hero) {
const offset = this.container.getBoundingClientRect().top - this.hero.getBoundingClientRect().top;
this.canvas.style.top = -offset + 'px';
this.canvas.style.height = this.boxHeight + 'px';
}
const dpr = window.devicePixelRatio || 1; const dpr = window.devicePixelRatio || 1;
const scale = Math.min(dpr, Math.sqrt(MAX_PIXELS / (this.width * this.boxHeight))); const scale = Math.min(dpr, Math.sqrt(MAX_PIXELS / (this.width * this.boxHeight)));
this.canvas.width = Math.max(1, Math.round(this.width * scale)); this.canvas.width = Math.max(1, Math.round(this.width * scale));