Files
hesu-JT/js/about-us-v3.js
T

115 lines
3.8 KiB
JavaScript
Raw Normal View History

2026-08-27 11:54:26 +08:00
/* ============================================================
About Us V3 — NIO-style animations
文字/Logo = 触发式(到达阈值 → 播完)
蒙版/背景缩放 = scrub 式(随滚动持续变化)
============================================================ */
(function () {
'use strict';
var s1 = document.getElementById('au-1');
var s3 = document.getElementById('au-3');
if (!s1) return;
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
document.documentElement.classList.add('rm');
return;
}
var pin1 = s1.closest('.au-pin');
var pin3 = s3 ? s3.closest('.au-pin') : null;
var mask1 = s1.querySelector('.au-mask');
var bg1 = s1.querySelector('.au-bg');
var mask3 = s3 ? s3.querySelector('.au-zoom-mask') : null;
function clamp(v, a, b) { return Math.max(a, Math.min(b, v)); }
function check() {
var y = window.scrollY;
var vh = window.innerHeight;
/* ---- au-1 ---- */
// 文字:触发式(过 30% → 加 .play)
var t1 = pin1.offsetTop + vh * 0.3;
s1.classList.toggle('play', y > t1);
// 蒙版:scrub 式(随滚动持续加深,0 → 1 跨 1.5 屏)
var p1 = clamp((y - pin1.offsetTop) / (vh * 1.5), 0, 1);
mask1.style.opacity = p1.toFixed(3);
// 背景:scrub 式(随滚动持续微缩 1.04 → 1)
bg1.style.transform = 'scale(' + (1.04 - 0.04 * p1).toFixed(4) + ')';
/* ---- au-3 ---- */
if (pin3) {
// 文字/Logo:触发式
var t3 = pin3.offsetTop + vh * 1.0;
s3.classList.toggle('play', y > t3);
// 黑幕:scrub 式(随滚动持续加深,0 → 0.8 跨 1.5 屏)
if (mask3) {
var p3 = clamp((y - pin3.offsetTop - vh * 0.5) / (vh * 1.5), 0, 1);
mask3.style.opacity = (p3 * 0.8).toFixed(3);
}
}
}
var ticking = false;
window.addEventListener('scroll', function () {
if (ticking) return;
ticking = true;
requestAnimationFrame(function () { check(); ticking = false; });
}, { passive: true });
window.addEventListener('resize', function () {
pin1 = s1.closest('.au-pin');
pin3 = s3 ? s3.closest('.au-pin') : null;
check();
}, { passive: true });
check();
})();
/* GPS carousel */
(function () {
'use strict';
var viewport = document.querySelector('.au-gps__viewport');
var track = document.querySelector('.au-gps__track');
var dotsWrap = document.querySelector('.au-gps__dots');
if (!viewport || !track || !dotsWrap) return;
var cards = Array.prototype.slice.call(track.children);
if (cards.length < 2) return;
var idx = 0, timer = null;
cards.forEach(function (_, i) {
var b = document.createElement('button');
b.setAttribute('aria-label', 'Slide ' + (i + 1));
b.addEventListener('click', function () { goTo(i); restart(); });
dotsWrap.appendChild(b);
});
var dots = Array.prototype.slice.call(dotsWrap.children);
function render() {
track.style.transform = 'translateX(' + (-idx * 100) + '%)';
dots.forEach(function (d, i) { d.classList.toggle('active', i === idx); });
}
function goTo(i) { idx = ((i % cards.length) + cards.length) % cards.length; render(); }
function next() { goTo(idx + 1); }
function start() { if (!timer) timer = setInterval(next, 4000); }
function stop() { clearInterval(timer); timer = null; }
function restart(){ stop(); start(); }
render(); start();
viewport.addEventListener('mouseenter', stop);
viewport.addEventListener('mouseleave', start);
document.addEventListener('visibilitychange', function () {
document.hidden ? stop() : start();
});
var x0 = null;
viewport.addEventListener('pointerdown', function (e) { x0 = e.clientX; });
window.addEventListener('pointerup', function (e) {
if (x0 === null) return;
var dx = e.clientX - x0; x0 = null;
if (Math.abs(dx) > 40) { dx < 0 ? next() : goTo(idx - 1); restart(); }
});
})();