new style rastafari

This commit is contained in:
ordinarthur 2026-03-20 22:27:12 +01:00
parent 90e229a763
commit 39e2c7a1a0
3 changed files with 29 additions and 100 deletions

Binary file not shown.

View File

@ -601,13 +601,16 @@ document.addEventListener('DOMContentLoaded', () => {
}); });
// ========================================================== // ==========================================================
// 6. AMBIENT WORKSHOP SOUND // 6. AMBIENT WORKSHOP SOUND (MP3)
// ========================================================== // ==========================================================
let audioCtx = null;
let soundOn = false; let soundOn = false;
let soundNodes = [];
let clickTimer = null; // Create audio element (preloaded, looped, low volume)
const ambientAudio = new Audio('/assets/atelier-ambiance.mp3');
ambientAudio.loop = true;
ambientAudio.volume = 0;
ambientAudio.preload = 'auto';
const headerNav = document.querySelector('.header-nav'); const headerNav = document.querySelector('.header-nav');
if (headerNav) { if (headerNav) {
@ -626,93 +629,18 @@ document.addEventListener('DOMContentLoaded', () => {
attachCursorHover([soundBtn]); attachCursorHover([soundBtn]);
} }
function createAudioContext() { // Smooth volume fade using GSAP
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
}
function generateBrownNoise(ctx, duration) {
const bufferSize = ctx.sampleRate * duration;
const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);
const data = buffer.getChannelData(0);
let lastOut = 0;
for (let i = 0; i < bufferSize; i++) {
const white = Math.random() * 2 - 1;
data[i] = (lastOut + (0.02 * white)) / 1.02;
lastOut = data[i];
data[i] *= 3.5;
}
return buffer;
}
function startAmbientSound() { function startAmbientSound() {
if (!audioCtx) createAudioContext(); ambientAudio.play().then(() => {
if (audioCtx.state === 'suspended') audioCtx.resume(); gsap.to(ambientAudio, { volume: 0.04, duration: 2, ease: 'power2.out' });
}).catch(() => {});
const noiseBuffer = generateBrownNoise(audioCtx, 4);
const noiseSource = audioCtx.createBufferSource();
noiseSource.buffer = noiseBuffer;
noiseSource.loop = true;
const lowpass = audioCtx.createBiquadFilter();
lowpass.type = 'lowpass';
lowpass.frequency.value = 180;
const gain = audioCtx.createGain();
gain.gain.value = 0;
gain.gain.linearRampToValueAtTime(0.045, audioCtx.currentTime + 2);
noiseSource.connect(lowpass);
lowpass.connect(gain);
gain.connect(audioCtx.destination);
noiseSource.start();
soundNodes.push({ source: noiseSource, gain: gain });
scheduleMetalClick();
}
function playMetalClick() {
if (!audioCtx || audioCtx.state !== 'running') return;
const osc = audioCtx.createOscillator();
osc.type = 'sine';
osc.frequency.value = 600 + Math.random() * 2400;
const gain = audioCtx.createGain();
gain.gain.value = 0.006 + Math.random() * 0.014;
gain.gain.exponentialRampToValueAtTime(
0.0001,
audioCtx.currentTime + 0.08 + Math.random() * 0.25
);
const filter = audioCtx.createBiquadFilter();
filter.type = 'bandpass';
filter.frequency.value = 1000 + Math.random() * 2000;
filter.Q.value = 12 + Math.random() * 25;
osc.connect(filter);
filter.connect(gain);
gain.connect(audioCtx.destination);
osc.start();
osc.stop(audioCtx.currentTime + 0.5);
}
function scheduleMetalClick() {
if (!soundOn) return;
const delay = 2000 + Math.random() * 7000;
clickTimer = setTimeout(() => {
if (!soundOn) return;
playMetalClick();
scheduleMetalClick();
}, delay);
} }
function stopAmbientSound() { function stopAmbientSound() {
if (clickTimer) { clearTimeout(clickTimer); clickTimer = null; } gsap.to(ambientAudio, {
soundNodes.forEach(({ source, gain }) => { volume: 0, duration: 1.2, ease: 'power2.in',
gain.gain.linearRampToValueAtTime(0, audioCtx.currentTime + 1); onComplete: () => ambientAudio.pause(),
setTimeout(() => { try { source.stop(); } catch (e) {} }, 1200);
}); });
soundNodes = [];
} }
function toggleSound() { function toggleSound() {

View File

@ -14,7 +14,7 @@
--pad: 2rem; --pad: 2rem;
} }
* { margin: 0; padding: 0; box-sizing: border-box; } * { margin: 0; padding: 0; box-sizing: border-box; cursor: none !important; }
html { font-size: 13px; } html { font-size: 13px; }
@ -35,32 +35,33 @@ body {
pointer-events: none; pointer-events: none;
z-index: 999998; z-index: 999998;
opacity: 0; opacity: 0;
transition: width 0.15s, height 0.15s; background: var(--clr-black);
transition: width 0.15s, height 0.15s, background 0.15s;
} }
.cad-h { .cad-h {
width: 40px; height: 1px; width: 40px; height: 2px;
background: var(--clr-black); transform: translateY(-1px);
transform: translateY(-0.5px);
} }
.cad-h.cad-hover { width: 56px; margin-left: -8px; } .cad-h.cad-hover { width: 56px; margin-left: -8px; background: var(--clr-red); }
.cad-v { .cad-v {
width: 1px; height: 40px; width: 2px; height: 40px;
background: var(--clr-black); transform: translateX(-1px);
transform: translateX(-0.5px);
} }
.cad-v.cad-hover { height: 56px; margin-top: -8px; } .cad-v.cad-hover { height: 56px; margin-top: -8px; background: var(--clr-red); }
.cad-center { .cad-center {
position: fixed; position: fixed;
width: 3px; height: 3px; width: 6px; height: 6px;
background: var(--clr-red); background: var(--clr-red);
pointer-events: none; pointer-events: none;
z-index: 999999; z-index: 999999;
opacity: 0; opacity: 0;
transform: translate(-1.5px, -1.5px); transform: translate(-3px, -3px);
transition: width 0.15s, height 0.15s;
} }
.cad-center.cad-hover { .cad-center.cad-hover {
width: 5px; height: 5px; width: 9px; height: 9px;
transform: translate(-2.5px, -2.5px); transform: translate(-4.5px, -4.5px);
background: var(--clr-black);
} }
.cad-coords { .cad-coords {
position: fixed; position: fixed;