import { qs, isMobileViewport } from '../utils/dom.js'; import { copyToClipboard, flashFeedback, flashClass } from '../utils/clipboard.js'; import { typewriterReveal } from '../animations/typewriter.js'; import { initFluidByteField } from '../animations/fluid-byte-field.js'; import { DISCORD_LOADER_SCRIPT, COPY_FEEDBACK_DURATION_MS } from '../config/constants.js'; const HERO_GREETING = 'Vyla Home'; function initVideoColorExtraction() { const videos = document.querySelectorAll('.hero-atmosphere-video'); if (videos.length === 0) return; console.log('Video color extraction initialized, found', videos.length, 'videos'); const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d', { willReadFrequently: true }); let animationFrameId; let frameCount = 0; let currentVideoColor = 'rgb(0, 0, 0)'; function extractColors() { const video = videos[0]; if (video.readyState < 2) { console.log('Video not ready, readyState:', video.readyState); animationFrameId = requestAnimationFrame(extractColors); return; } try { canvas.width = 64; canvas.height = 64; ctx.drawImage(video, 0, 0, 64, 64); const imageData = ctx.getImageData(0, 0, 64, 64); const data = imageData.data; let r = 0, g = 0, b = 0; let count = 0; for (let i = 0; i < data.length; i += 4) { r += data[i]; g += data[i + 1]; b += data[i + 2]; count++; } r = Math.round(r / count); g = Math.round(g / count); b = Math.round(b / count); currentVideoColor = `rgb(${r}, ${g}, ${b})`; const dominantColorTransparent = `rgba(${r}, ${g}, ${b}, 0.5)`; document.documentElement.style.setProperty('--video-dominant-color', currentVideoColor); document.documentElement.style.setProperty('--video-dominant-color-transparent', dominantColorTransparent); if (window.scrollY === 0) { document.documentElement.style.setProperty('--color-bg', currentVideoColor); } frameCount++; if (frameCount % 30 === 0) { console.log('Frame', frameCount, '- Extracted color:', currentVideoColor); console.log('CSS variable set:', getComputedStyle(document.documentElement).getPropertyValue('--video-dominant-color')); } } catch (e) { console.error('Error extracting video colors:', e); } animationFrameId = requestAnimationFrame(extractColors); } function handleScroll() { const scrollY = window.scrollY; const heroHeight = window.innerHeight; const scrollProgress = Math.min(scrollY / (heroHeight * 0.5), 1); const videoColorRGB = currentVideoColor.match(/\d+/g); if (videoColorRGB) { const r = Math.round(parseInt(videoColorRGB[0]) * (1 - scrollProgress)); const g = Math.round(parseInt(videoColorRGB[1]) * (1 - scrollProgress)); const b = Math.round(parseInt(videoColorRGB[2]) * (1 - scrollProgress)); const fadedColor = `rgb(${r}, ${g}, ${b})`; document.documentElement.style.setProperty('--color-bg', fadedColor); } } animationFrameId = requestAnimationFrame(extractColors); window.addEventListener('scroll', handleScroll, { passive: true }); handleScroll(); videos.forEach(video => { video.addEventListener('pause', () => { console.log('Video paused, stopping color extraction'); cancelAnimationFrame(animationFrameId); }); video.addEventListener('play', () => { console.log('Video playing, starting color extraction'); animationFrameId = requestAnimationFrame(extractColors); }); }); } function initHeroTitle() { const heroTitle = qs('.hero-title'); if (heroTitle) typewriterReveal(heroTitle, HERO_GREETING); } function initDiscordCopyBar() { const copyBtn = document.getElementById('copy-discord-btn'); const copyLabel = document.getElementById('copy-discord-label'); const copyIcon = document.getElementById('copy-discord-icon'); if (!copyBtn) return; copyBtn.addEventListener('click', async () => { await copyToClipboard(DISCORD_LOADER_SCRIPT); if (copyIcon) flashClass(copyIcon, 'copied', COPY_FEEDBACK_DURATION_MS); }); } function initHeroCopyButton() { const heroCopyScriptBtn = document.getElementById('hero-copy-script-btn'); if (!heroCopyScriptBtn) return; heroCopyScriptBtn.addEventListener('click', async () => { await copyToClipboard(DISCORD_LOADER_SCRIPT); flashFeedback(heroCopyScriptBtn, 'Copied!', COPY_FEEDBACK_DURATION_MS); }); } function initCtaCopyButton() { const ctaCopyScriptBtn = document.getElementById('cta-copy-script-btn'); if (!ctaCopyScriptBtn) return; ctaCopyScriptBtn.addEventListener('click', async () => { await copyToClipboard(DISCORD_LOADER_SCRIPT); flashFeedback(ctaCopyScriptBtn, 'Copied!', COPY_FEEDBACK_DURATION_MS); }); } export function initHeroSection() { initHeroTitle(); initDiscordCopyBar(); initHeroCopyButton(); initCtaCopyButton(); initVideoColorExtraction(); initFluidByteField('hero-byte-overlay'); initFluidByteField('cta-byte-overlay'); }