// Studio page — vanilla fade-carousel + tab sync + per-slide choreography. // Replaces Bootstrap Carousel/Tab, jQuery, and backstretch. Keeps DrawFillSVG // (window.DrawFillSVG, self-exposed from the v4-script bundle). // --- shared chrome: navbar hide/show on scroll (ported from jQuery dw_hidenav) --- (function () { const navbar = document.querySelector('.navbar'); if (!navbar) return; const title = document.querySelector('.site-title a'); const headerHeight = navbar.offsetHeight; let previousTop = 0; window.addEventListener('scroll', function () { const currentTop = window.scrollY; if (currentTop < previousTop) { if (currentTop > 0 && navbar.classList.contains('fixed')) { navbar.classList.add('visible'); if (title) title.classList.remove('light'); } else { navbar.classList.remove('visible', 'fixed'); if (title) title.classList.add('light'); } } else { navbar.classList.remove('visible'); if (currentTop > headerHeight && !navbar.classList.contains('fixed')) { navbar.classList.add('fixed'); } } previousTop = currentTop; }, { passive: true }); })(); document.querySelectorAll('.nav-toggle').forEach(function (el) { el.addEventListener('click', function (e) { e.preventDefault(); el.classList.toggle('active'); }); }); // --- studio fade-carousel --- (function () { const stage = document.getElementById('studio-caro'); const caro = document.getElementById('caro'); if (!stage || !caro) return; const card = stage.querySelector('.dw-studio-stage') || stage; // contained rounded hero card that carries the per-slide bg const slides = Array.from(caro.querySelectorAll('.dw-fade-slide')); const tabs = Array.from(document.querySelectorAll('.dw-studio-tab')); const panes = Array.from(document.querySelectorAll('#studio-tab .tab-pane')); const bg = stage.querySelector('.dw-studio-bg'); const video = stage.querySelector('.dw-studio-video'); // camera → Media slide const tv = stage.querySelector('.dw-studio-tv'); // grayscale → fact intro const title = document.querySelector('.site-title a'); const studioTab = tabs.find((t) => t.getAttribute('href') === '#studio') || tabs[0]; const GRADS = ['caro-grad', 'caro-grad2', 'caro-grad3', 'caro-grad5', 'caro-grad-dadada']; // per slide: gradient class · background image · show video · navbar-title light // Slides 0-4 are the tabbed sections; 5-7 the fact intro; 8 the Projects hero. const CONFIG = [ { grad: 'caro-grad5', img: stage.dataset.bg0 || null, video: false, light: true, filter: 'url(#dw-duotone-slate)' }, // 0 Studio (slate-duotone hero) { grad: 'caro-grad2', img: null, video: false, light: true }, // 1 Web/Dev (was UX) { grad: 'caro-grad3', img: null, video: false, light: false }, // 2 Graphic { grad: 'caro-grad5', img: null, video: true, light: true }, // 3 Media { grad: 'caro-grad5', img: stage.dataset.bg5 || null, video: false, light: true }, // 4 Art { grad: 'caro-grad5', img: null, video: false, tv: true, light: true }, // 5 fact: web sites { grad: 'caro-grad5', img: null, video: false, tv: true, light: true }, // 6 fact: stars { grad: 'caro-grad5', img: null, video: false, tv: true, light: true }, // 7 fact: brain { grad: 'caro-grad-dadada', img: null, video: false, light: true }, // 8 Projects (#dadada card) ]; const INTERVAL = 5000; let index = 0; let timer = null; function drawSVGs(slide) { if (!window.DrawFillSVG) return; slide.querySelectorAll('svg[id]').forEach(function (svg) { try { new window.DrawFillSVG({ elementId: svg.id }).replay(); } catch (e) { /* svg not animatable — skip */ } }); } // Set the hero carousel slide (slide visibility, gradient, bg image, video/tv, // navbar-title colour). Does NOT touch the subnav tabs or content panes — those // are driven by setActiveTab, so the Wonder auto-cycle and the content-only // Projects tab can move the hero and the active tab independently. function setHero(i) { i = (i + slides.length) % slides.length; index = i; const cfg = CONFIG[i]; slides.forEach((s, n) => { const on = n === i; s.classList.toggle('active', on); // reveal the active slide's hidden content (.animac.hide-svg, #brain.hide-svg …) if (on) s.querySelectorAll('.hide-svg').forEach((el) => el.classList.remove('hide-svg')); }); GRADS.forEach((g) => card.classList.remove(g)); card.classList.add(cfg.grad); if (bg) { bg.style.backgroundImage = cfg.img ? 'url("' + cfg.img + '")' : ''; bg.style.filter = cfg.filter || ''; // slate duotone on the Studio hero only } if (video) { if (cfg.video) { video.style.display = 'block'; video.play().catch(function () {}); } else { video.pause(); video.style.display = 'none'; } } if (tv) { if (cfg.tv) { tv.style.display = 'block'; tv.play().catch(function () {}); } else { tv.pause(); tv.style.display = 'none'; } } if (title) title.classList.toggle('light', cfg.light); drawSVGs(slides[i]); } // Mark a subnav tab active and show its matching content pane, matched by the // tab's href hash → pane id (#studio → id="studio", #projects → id="projects"). // Tabs with no pane (Wonder) simply hide every pane. function setActiveTab(tab) { tabs.forEach((t) => t.classList.toggle('active', t === tab)); const hash = tab ? tab.getAttribute('href') || '' : ''; const id = hash.charAt(0) === '#' ? hash.slice(1) : ''; panes.forEach((p) => p.classList.toggle('active', p.id === id)); } // "Craft" (the .dw-studio-wonder tab) auto-rotates the hero through the fact // slides (5,6,7) once and stops on the last, leaving the Craft tab + pane active. // Every other tab just switches on click — no autoplay. const WONDER = [5, 6, 7]; let wonderTimer = null; function stopWonder() { if (wonderTimer) { window.clearTimeout(wonderTimer); wonderTimer = null; } } function runWonder() { stopWonder(); let step = 0; (function tick() { setHero(WONDER[step]); step++; if (step < WONDER.length) wonderTimer = window.setTimeout(tick, INTERVAL); // ends on the last fact slide — the Craft tab + its pane stay active })(); } tabs.forEach(function (t) { t.addEventListener('click', function (e) { e.preventDefault(); stopWonder(); setActiveTab(t); if (t.classList.contains('dw-studio-wonder')) runWonder(); else setHero(parseInt(t.dataset.slide, 10) || 0); }); }); // No autoplay — the carousel advances only on subnav clicks (Wonder runs its own set). setActiveTab(studioTab); setHero(0); })();