(() => { 'use strict'; const body = document.querySelector('body.home-v260'); if (!body || window.__DBC_HOME_V260__) return; window.__DBC_HOME_V260__ = true; const root = document.documentElement; const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)'); const header = document.querySelector('.site-header'); const progress = document.querySelector('.v260-progress'); const progressLinks = progress ? Array.from(progress.querySelectorAll('a[data-v260-progress]')) : []; const sections = progressLinks .map((link) => ({ id: link.dataset.v260Progress, link, section: document.getElementById(link.dataset.v260Progress) })) .filter((item) => item.section); function syncHeaderHeight() { if (!header) return; const height = Math.round(header.getBoundingClientRect().height); if (height > 0) root.style.setProperty('--dbc-header-height', `${height}px`); } syncHeaderHeight(); if (header && 'ResizeObserver' in window) { const headerObserver = new ResizeObserver(syncHeaderHeight); headerObserver.observe(header); } let activeId = ''; function setActive(id) { if (!id || id === activeId) return; activeId = id; if (progress) progress.classList.toggle('is-on-hero', id === 'home'); sections.forEach((item) => { const active = item.id === id; item.link.classList.toggle('is-active', active); if (active) item.link.setAttribute('aria-current', 'location'); else item.link.removeAttribute('aria-current'); }); } const visibility = new Map(sections.map((item) => [item.id, 0])); function chooseActiveSection() { let current = sections[0]; let highest = -1; sections.forEach((item) => { const ratio = visibility.get(item.id) || 0; if (ratio > highest) { highest = ratio; current = item; } }); if (current) setActive(current.id); } if ('IntersectionObserver' in window) { const activeObserver = new IntersectionObserver((entries) => { entries.forEach((entry) => { const item = sections.find((candidate) => candidate.section === entry.target); if (item) visibility.set(item.id, entry.isIntersecting ? entry.intersectionRatio : 0); }); chooseActiveSection(); }, { rootMargin: '-18% 0px -18% 0px', threshold: [0, .08, .18, .32, .5, .7] }); sections.forEach((item) => activeObserver.observe(item.section)); } else { setActive((location.hash || '#home').slice(1)); } sections.forEach((item) => { item.link.addEventListener('click', () => setActive(item.id)); }); const revealSections = Array.from(document.querySelectorAll('.v260-screen')); function revealAll() { revealSections.forEach((section) => section.classList.add('is-v260-visible')); } if (reducedMotion.matches || !('IntersectionObserver' in window)) { revealAll(); } else { body.classList.add('v260-motion-ready'); const revealObserver = new IntersectionObserver((entries, observer) => { entries.forEach((entry) => { if (!entry.isIntersecting) return; entry.target.classList.add('is-v260-visible'); observer.unobserve(entry.target); }); }, { rootMargin: '0px 0px -12% 0px', threshold: .08 }); revealSections.forEach((section) => revealObserver.observe(section)); } function handleReducedMotion(event) { if (!event.matches) return; body.classList.remove('v260-motion-ready'); revealAll(); } if (typeof reducedMotion.addEventListener === 'function') { reducedMotion.addEventListener('change', handleReducedMotion); } function syncParticleCaptionLanguage() { const english = root.dataset.lang === 'en' || root.lang.toLowerCase().startsWith('en'); const brand = document.querySelector('.dbc-bioten-particle-caption .dbc-bioten-caption-brand'); const text = document.querySelector('.dbc-bioten-particle-caption .dbc-bioten-caption-text'); if (brand) { brand.textContent = english ? 'DBC · We Innovate Future Applications' : '世界杯竞猜官网 · 创新未来应用'; } if (text) { text.textContent = english ? 'BIOTEN · Fiber-Based Food Packaging Barrier System' : '博碳 · 纸基食品包装阻隔工程系统'; } } syncParticleCaptionLanguage(); document.addEventListener('dbc:languagechange', () => { window.requestAnimationFrame(() => { syncParticleCaptionLanguage(); chooseActiveSection(); }); }); const languageObserver = new MutationObserver(() => { window.requestAnimationFrame(syncParticleCaptionLanguage); }); languageObserver.observe(root, { attributes: true, attributeFilter: ['lang', 'data-lang'] }); })();