From 6e88cf4cd49c538b9d65bb69ef55f7c95a5cd6d5 Mon Sep 17 00:00:00 2001
From: Linus Olofsson <61837116+LinusOlofsson-maker@users.noreply.github.com>
Date: Thu, 21 May 2026 04:51:34 +0200
Subject: [PATCH] fix(logo-threads): Y-align to cross logo (#21)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* fix(pulse): split halves now meet simultaneously + no backtracking
Two bugs fixed after Linus feedback:
1. Path-form: top/bottom split halves used Bezier curves that could
loop back on themselves when entry.x lay outside box X-range.
Now use clamped startX/endX (max(xL+r, min(xR-r, entry.x))) so
pathen alltid rör sig framåt (entry.x → exit.x), aldrig vänder.
2. Synchronized meeting: previously each blob moved at fixed velocity
along its own path → shorter path arrived first and waited.
Now both blobs share a phase2T (0→1) progress fraction, so they
meet at exit-point simultaneously. The path with different length
simply moves at a slightly different speed (averaged). Phase2
duration based on avg(topLen,bottomLen)/velocity so total animation
time stays consistent.
* feat: logo-pulse with pink->green color transition
Adds a 4th pulse target: the IMAGES BY OLOFSSON hero-text logo.
20% chance per pulse-slot when logo is visible (footer scrolled in).
Flow:
1. New purple wave-thread on bottom-left (mirror of cyan wave1 on right)
2. Pulse glides in along purple thread to logo-left edge
3. Pulse enters logo + tints smoky-path stroke pink (#e879f9) + adds
pink text-shadow halo on h1
4. Mid-passage: tint transitions to green (#4fd1c5) — matches default
smoke + cyan glow
5. Pulse exits logo via wave1 (existing cyan thread on right)
6. Logo tint reverts to default (white smokeShift animation)
CSS-side: data-logo-tint attribute on #text-wrapper drives stroke +
text-shadow overrides with 0.6-0.8s transitions for smooth fade.
* fix(logo-pulse): dynamic paths anchored to logo + 50% probability
Previous version tried to use existing wave1+threadPurple paths for
logo-pulse glide-in/out, but those paths are in SVG-fixed coordinates
that don't align with logo's viewport position when hero is scrolled
into view. wave1 has translateX(2283) which pushes it off-screen for
ultrawide viewports.
Fix: build dynamic Bezier paths anchored to the logo's actual
getBoundingClientRect() position at pulse-time:
- Entry path: from (offLeft, logoY+dipOffset) curves up into logo-left
- Exit path: from logo-right curves up to (offRight, logoY-riseOffset)
Paths are appended to box-trail-group, used for one pulse, then
removed in cleanup. No reliance on fixed wave-thread coordinates.
Also raises LOGO_PROBABILITY 20%->50% so the effect is visible more
often when hero is in view.
* fix(logo-pulse): visible entry/exit threads + restore pulse color after
Two bugs fixed:
1. Entry+exit paths were stroke=transparent — pulse appeared to spawn
out of nothing. Now stroke=url(#gradPurple) on entry (subtle pink
thread visible from off-screen left) and stroke=url(#gradMain) on
exit (cyan thread visible going off-screen right). Both at
stroke-width 0.8 + opacity 0.55 to match other wave-thread style.
2. After logo-pulse completed, pulse-gradient stops were left in pink
state — next regular wave-pulse rendered as stale pink instead of
cyan/theme color. Now updatePulseColors(false) is called in cleanup
to restore default cyan-tema.
* fix(logo-pulse): entry/exit threads now properly visible
Previous version used gradient strokes (gradPurple/gradMain) which
have stop-opacity 0 at ends + 0.45 mid, multiplied by path-opacity
0.55 = ~0.25 effective opacity. Practically invisible.
Now solid stroke colors (#e879f9 pink, #4fd1c5 cyan), stroke-width 2
(was 0.8), opacity 0.85 (was 0.55), plus pulseGlowMid filter for soft
halo. Should be clearly visible from off-screen edges to logo.
* feat(logo-pulse): permanent visible threads (no dynamic creation)
Previously dynamic paths were built/destroyed per pulse, were too
thick (stroke-width 2 + glow), and persisted incorrectly causing
visual artifacts.
Now:
- threadLogoIn: permanent purple wave-thread, same style as other
wave-threads (gradPurple stroke, stroke-width 0.7, opacity 0.55)
- threadLogoOut: permanent cyan wave-thread (gradMain stroke 0.7,
opacity 0.50)
- runLogoPulse uses these permanent paths via getPointAtLength
- getScreenCTM converts SVG-coords to screen-coords so pulse follows
thread even with scroll/viewport variance
* fix(logo-threads): align Y-coords to actually cross logo
Logo Y-center is approx 287 in screen-coords. Previous thread Y-coords
(400-600) only grazed logo-bottom or sat entirely below it. Adjusted:
- threadLogoIn: M-1000 500 Q 200 350 850 287 T 2600 200
Kommer från nedre-vänster (Y=500), kurvar UPP till logo-center
(Y=287), fortsätter upp till övre-höger (Y=200)
- threadLogoOut: M-1000 350 Q 400 200 850 287 T 2600 500
Kommer från övre-vänster (Y=350), genom logo-center (Y=287), ner
till nedre-höger (Y=500) — vertikalt motsatt entry-tråd
---
src/components/WaveBackground.astro | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/WaveBackground.astro b/src/components/WaveBackground.astro
index 1140b31..af8875e 100644
--- a/src/components/WaveBackground.astro
+++ b/src/components/WaveBackground.astro
@@ -72,8 +72,8 @@ const pulseCore = theme === 'purple' ? '#fdf4ff' : '#f0fdfa';
-
-
+
+