|
1 | 1 | <script lang="ts"> |
2 | 2 | import { Canvas } from "@threlte/core"; |
| 3 | + import { afterNavigate } from "$app/navigation"; |
3 | 4 | import MatrixRain from "$features/matrix-rain/components/MatrixRain.svelte"; |
4 | 5 | import MusicPlayer from "$features/music/components/MusicPlayer.svelte"; |
5 | 6 | import Score from "$features/synthwave/components/Score.svelte"; |
|
8 | 9 | import MetallicText from "$lib/components/MetallicText.svelte"; |
9 | 10 | import { CONTROLS_DELAY } from "$lib/config"; |
10 | 11 | import gsap from "gsap"; |
11 | | - import { onMount } from "svelte"; |
12 | 12 |
|
| 13 | + let showVisuals: boolean | null = $state(null); |
13 | 14 | let heroEl: HTMLElement | null = $state(null); |
14 | | - let scoreVisible: boolean | null = $state(null); |
15 | | - let matrixRainVisible: boolean | null = $state(null); |
16 | 15 | let synthwaveVisible = $state(true); |
| 16 | + let externalNavigation = $state(false); |
| 17 | +
|
| 18 | + afterNavigate(({ from }) => { |
| 19 | + if (from?.url) { |
| 20 | + if (showVisuals === null) { |
| 21 | + showVisuals = true; |
| 22 | + } |
| 23 | + return; |
| 24 | + } |
| 25 | +
|
| 26 | + externalNavigation = true; |
17 | 27 |
|
18 | | - $effect(() => { |
19 | 28 | const tl = gsap.timeline(); |
20 | 29 | tl.from("#title", { opacity: 0, duration: 1, ease: "power1.out" }); |
21 | 30 | tl.delay(1); |
|
26 | 35 | duration: 3, |
27 | 36 | ease: "power1.out", |
28 | 37 | }); |
29 | | - }); |
30 | 38 |
|
31 | | - $effect(() => { |
32 | 39 | setTimeout(() => { |
33 | | - if (scoreVisible === null) { |
34 | | - scoreVisible = true; |
35 | | - } |
36 | | - if (matrixRainVisible === null) { |
37 | | - matrixRainVisible = true; |
| 40 | + if (showVisuals === null) { |
| 41 | + showVisuals = true; |
38 | 42 | } |
39 | 43 | }, CONTROLS_DELAY); |
40 | 44 | }); |
41 | | -
|
42 | | - onMount(() => { |
43 | | - const scoreObserver = new IntersectionObserver( |
44 | | - ([entry]) => { |
45 | | - if (scoreVisible !== null) { |
46 | | - scoreVisible = entry.isIntersecting; |
47 | | - } |
48 | | - }, |
49 | | - { threshold: 0.9 }, |
50 | | - ); |
51 | | - const matrixRainObserver = new IntersectionObserver( |
52 | | - ([entry]) => { |
53 | | - if (matrixRainVisible !== null) { |
54 | | - matrixRainVisible = entry.isIntersecting; |
55 | | - } |
56 | | - }, |
57 | | - { threshold: 0.1 }, |
58 | | - ); |
59 | | - const synthwaveObserver = new IntersectionObserver( |
60 | | - ([entry]) => { |
61 | | - synthwaveVisible = entry.isIntersecting; |
62 | | - }, |
63 | | - { threshold: 0.1 }, |
64 | | - ); |
65 | | -
|
66 | | - if (heroEl) { |
67 | | - matrixRainObserver.observe(heroEl); |
68 | | - synthwaveObserver.observe(heroEl); |
69 | | - scoreObserver.observe(heroEl); |
70 | | - } |
71 | | -
|
72 | | - return () => { |
73 | | - matrixRainObserver.disconnect(); |
74 | | - synthwaveObserver.disconnect(); |
75 | | - scoreObserver.disconnect(); |
76 | | - }; |
77 | | - }); |
78 | 45 | </script> |
79 | 46 |
|
80 | 47 | <MusicPlayer /> |
81 | 48 |
|
82 | | -{#if scoreVisible} |
| 49 | +{#if showVisuals} |
83 | 50 | <Score /> |
84 | 51 | {/if} |
85 | 52 |
|
86 | | -{#if matrixRainVisible} |
| 53 | +{#if showVisuals} |
87 | 54 | <div class="fixed z-[-30] h-[75vh] w-screen"> |
88 | 55 | <MatrixRain /> |
89 | 56 | </div> |
|
99 | 66 | </div> |
100 | 67 | {/if} |
101 | 68 |
|
102 | | -<div class="flex h-screen flex-col items-center" bind:this={heroEl}> |
| 69 | +<div id="hero" class="flex h-screen flex-col items-center" bind:this={heroEl}> |
103 | 70 | <div id="title" class="mt-[20vh] flex flex-col items-center"> |
104 | | - <h1 class="mb-[-0.4em] text-5xl sm:text-7xl md:text-8xl"> |
105 | | - <MetallicText>Neal Wang</MetallicText> |
106 | | - </h1> |
| 71 | + <div |
| 72 | + class={`tooltip ${externalNavigation && showVisuals ? "tooltip-open" : ""}`} |
| 73 | + data-tip="Click me!" |
| 74 | + > |
| 75 | + <a class="cursor-pointer" href="/bio"> |
| 76 | + <h1 |
| 77 | + id="name" |
| 78 | + class="mb-[-0.4em] text-5xl sm:text-7xl md:text-8xl" |
| 79 | + > |
| 80 | + <MetallicText>Neal Wang</MetallicText> |
| 81 | + </h1> |
| 82 | + </a> |
| 83 | + </div> |
107 | 84 | <div id="glitch"> |
108 | 85 | <Glitch /> |
109 | 86 | </div> |
110 | 87 | </div> |
111 | 88 | </div> |
112 | 89 |
|
113 | 90 | <style> |
114 | | - * { |
115 | | - @apply cursor-none; |
116 | | - } |
117 | | -
|
118 | 91 | #synthwave-background { |
119 | 92 | background: linear-gradient( |
120 | 93 | to bottom, |
|
123 | 96 | oklch(15% 0.09 281.288) |
124 | 97 | ); |
125 | 98 | } |
| 99 | +
|
| 100 | + #hero { |
| 101 | + @apply cursor-none; |
| 102 | + } |
| 103 | +
|
| 104 | + #name { |
| 105 | + view-transition-name: name; |
| 106 | + } |
126 | 107 | </style> |
0 commit comments