From 9e51b7727358b8c3f47906bb0312f5709bdd082c Mon Sep 17 00:00:00 2001 From: djoser Date: Mon, 27 Jul 2026 17:20:59 +0200 Subject: [PATCH] QOL dimming shader --- index.html | 24 ------------------------ src/app.ts | 20 +++++++------------- src/data/scenes/about.ts | 2 +- src/engine/renderer.ts | 3 ++- src/engine/shaders/fullscreen.wgsl | 4 ++++ src/ui/overlay.ts | 8 -------- 6 files changed, 14 insertions(+), 47 deletions(-) diff --git a/index.html b/index.html index 819833a..3965477 100644 --- a/index.html +++ b/index.html @@ -101,29 +101,6 @@ white-space: pre-line; } - /* cycle button */ - #cycle-button { - font: inherit; - font-size: clamp(0.8rem, 1.4vw, 1rem); - letter-spacing: 0.1em; - padding: 0.7rem 2.4rem; - background: rgba(22, 48, 78, 0.35); - border: 1.5px solid rgba(144, 184, 220, 0.6); - color: #fff; - border-radius: 999px; - cursor: pointer; - backdrop-filter: blur(2px); - transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease; - } - #cycle-button:hover { - background: rgba(40, 90, 140, 0.5); - border-color: rgba(180, 210, 240, 0.9); - box-shadow: 0 0 18px rgba(90, 170, 255, 0.4); - } - #cycle-button:active { - transform: scale(0.97); - } - /* ---------- resume section ---------- */ @keyframes resumeFadeIn { from { opacity: 0; transform: translateX(-50%) translateY(18px); } @@ -481,7 +458,6 @@

-
diff --git a/src/app.ts b/src/app.ts index 135dd18..5db9f87 100644 --- a/src/app.ts +++ b/src/app.ts @@ -2,7 +2,8 @@ import { Renderer, UiState } from './engine/renderer' import { Input } from './ui/input' import { DomOverlay } from './ui/overlay' import { Router, Route } from './router' -import { PAGES, PROJECTS_SCENE, RESUME_SCENE } from './data/pages' +import { PROJECTS_SCENE, RESUME_SCENE } from './data/pages' +import { SCENES } from './data/scenes' const DPR_CAP = 2 @@ -31,21 +32,10 @@ export class App { async start(): Promise { this.input = new Input() - // Build SceneContent[] from PAGES for the overlay - const scenes = PAGES.map((p) => ({ - title: p.title, - subtitle: p.subtitle, - body: p.body, - })) - - this.overlay = new DomOverlay(scenes, { + this.overlay = new DomOverlay(SCENES, { onNavClick: (s) => { this.router.navigate(Router.sceneToBasePath(s)) }, - onButtonClick: () => { - const next = (this.scene + 1) % 4 - this.router.navigate(Router.sceneToBasePath(next)) - }, onNavigate: (path) => { this.router.navigate(path) }, @@ -142,11 +132,15 @@ export class App { this.computeStemMultipliers(time) + // dim the shader when on any non-home scene + const dim = this.scene === 0 ? 0.0 : 0.4 + const state: UiState = { resolution: this.res, time, scene: this.scene, mouse: this.mouse, + dim, stemMultipliers: this.stemMultipliers, } this.renderer.render(state) diff --git a/src/data/scenes/about.ts b/src/data/scenes/about.ts index a026f5c..e286f06 100644 --- a/src/data/scenes/about.ts +++ b/src/data/scenes/about.ts @@ -2,6 +2,6 @@ import type { SceneContent } from './index' export const about: SceneContent = { title: 'ABOUT', - subtitle: 'Who I am', + subtitle: 'Who I am and what I do', body: 'My name is Ahmed Alaa Ahmed Mohamed (aka Djoser/Djosen/Inedited), I\'m a passionate creative software engineer and game developer. ', } diff --git a/src/engine/renderer.ts b/src/engine/renderer.ts index 9bb451d..61a9f36 100644 --- a/src/engine/renderer.ts +++ b/src/engine/renderer.ts @@ -8,6 +8,7 @@ export interface UiState { time: number scene: number mouse: Float32Array + dim: number stemMultipliers: Float32Array } @@ -81,7 +82,7 @@ export class Renderer { d[4] = state.mouse[0] d[5] = state.mouse[1] // d[6], d[7]: padding — left as zero - // d[8]-d[11]: date — left as zero + d[8] = state.dim // u.date.x — dim factor for non-home scenes // d[12]-d[15]: sampleRate — left as zero d.set(state.stemMultipliers, 16) this.device.queue.writeBuffer(this.uniformBuffer, 0, this.uniformData) diff --git a/src/engine/shaders/fullscreen.wgsl b/src/engine/shaders/fullscreen.wgsl index 30d894b..8c15fb1 100644 --- a/src/engine/shaders/fullscreen.wgsl +++ b/src/engine/shaders/fullscreen.wgsl @@ -100,5 +100,9 @@ fn fs(in: VsOut) -> @location(0) vec4 { // soft cursor glow finalColor += exp(-distMouse * 4.0) * 0.03 * sceneAccent; + // ---------- dim when not on the home page (u.date.x controls it) ---------- + let dim = u.date.x; + finalColor = mix(finalColor, vec3(0.0), dim); + return vec4(finalColor * vignette, 1.0); } diff --git a/src/ui/overlay.ts b/src/ui/overlay.ts index ff54579..0cbcc22 100644 --- a/src/ui/overlay.ts +++ b/src/ui/overlay.ts @@ -10,7 +10,6 @@ interface SceneContent { export interface OverlayCallbacks { onNavClick: (scene: number) => void - onButtonClick: () => void onNavigate: (path: string) => void } @@ -139,7 +138,6 @@ export class DomOverlay { private readonly sceneContentEl: HTMLElement private readonly projectsSectionEl: HTMLElement private readonly resumeSectionEl: HTMLElement - private readonly cycleBtnEl: HTMLElement private readonly scenes: SceneContent[] constructor(scenes: SceneContent[], callbacks: OverlayCallbacks) { @@ -151,14 +149,11 @@ export class DomOverlay { this.sceneContentEl = document.getElementById('scene-content') as HTMLElement this.projectsSectionEl = document.getElementById('projects-section') as HTMLElement this.resumeSectionEl = document.getElementById('resume-section') as HTMLElement - this.cycleBtnEl = document.getElementById('cycle-button') as HTMLElement this.navItems.forEach((item, i) => { item.addEventListener('click', () => callbacks.onNavClick(i)) }) - this.cycleBtnEl.addEventListener('click', () => callbacks.onButtonClick()) - // delegate clicks inside projects section → onNavigate callback this.projectsSectionEl.addEventListener('click', (e) => { const target = e.target as HTMLElement @@ -227,16 +222,13 @@ export class DomOverlay { this.sceneContentEl.classList.remove('hidden') this.projectsSectionEl.classList.remove('visible') this.resumeSectionEl.classList.remove('visible') - this.cycleBtnEl.style.display = '' if (scene === PROJECTS_SCENE) { this.sceneContentEl.classList.add('hidden') this.projectsSectionEl.classList.add('visible') - this.cycleBtnEl.style.display = 'none' } else if (scene === RESUME_SCENE) { this.sceneContentEl.classList.add('hidden') this.resumeSectionEl.classList.add('visible') - this.cycleBtnEl.style.display = 'none' } this.navItems.forEach((item, i) => {