网址提交
This commit is contained in:
+119
@@ -0,0 +1,119 @@
|
||||
/* ============================================================
|
||||
About Us — CSS sticky pin + rAF scroll-linked (no GSAP)
|
||||
Smoothest approach: CSS position:sticky handles the pin
|
||||
(native GPU compositing), rAF drives the cross-fade timeline.
|
||||
Stage 1 (au-1): intro(screen1) -> slogan(screen2)
|
||||
Stage 2 (au-3): Strong Resources(screen3) -> zoom+logo(screen4)
|
||||
============================================================ */
|
||||
(function () {
|
||||
var s1 = document.querySelector('#au-1');
|
||||
var s3 = document.querySelector('#au-3');
|
||||
if (!s1) return;
|
||||
|
||||
var bg = s1.querySelector('.au-bg');
|
||||
var intro = s1.querySelector('.au-inner');
|
||||
var corner = s1.querySelector('.au-corner-img');
|
||||
var mask = s1.querySelector('.au-mask');
|
||||
var layer = s1.querySelector('.au-slogan-layer');
|
||||
var sl = s1.querySelector('.au-slogan');
|
||||
var cn = s1.querySelector('.au-slogan-cn');
|
||||
|
||||
var head = s3 ? s3.querySelector('.au-sec-head') : null;
|
||||
var zoom = s3 ? s3.querySelector('.au-zoom-img') : null;
|
||||
var zoomMask = s3 ? s3.querySelector('.au-zoom-mask') : null;
|
||||
var reveal = s3 ? s3.querySelector('.au-reveal') : null;
|
||||
|
||||
function clamp(v, a, b) { return Math.max(a, Math.min(b, v)); }
|
||||
function lerp(a, b, t) { return a + (b - a) * clamp(t, 0, 1); }
|
||||
|
||||
var start1 = 0, start3 = 0;
|
||||
function measure() {
|
||||
function dt(el) { var r = el.getBoundingClientRect(); return r.top + window.scrollY; }
|
||||
start1 = dt(s1);
|
||||
if (s3) start3 = dt(s3);
|
||||
}
|
||||
|
||||
function update() {
|
||||
var vh = window.innerHeight;
|
||||
|
||||
/* ---- au-1 (pin 2vh): intro held -> cross-fade to slogan ---- */
|
||||
var p = clamp((window.scrollY - start1) / vh, 0, 2); // 0 -> 2
|
||||
|
||||
// bg: subtle cinematic scale throughout
|
||||
if (bg) bg.style.transform = 'scale(' + lerp(1.04, 1, p / 2).toFixed(4) + ')';
|
||||
|
||||
// intro (screen 1): held 0-0.3, fades up 0.3-0.6
|
||||
var introT = clamp((p - 0.3) / 0.3, 0, 1);
|
||||
if (intro) { intro.style.opacity = String(1 - introT); intro.style.transform = 'translateY(' + (-introT * 30).toFixed(1) + 'px)'; }
|
||||
if (corner) corner.style.opacity = String(1 - introT);
|
||||
|
||||
// mask: darkens 0.3-0.6
|
||||
if (mask) mask.style.opacity = String(introT);
|
||||
|
||||
// slogan (screen 2): triggered CSS transition at threshold (NIO-style auto rise-up)
|
||||
if (layer) layer.classList.toggle('is-current', p >= 0.5);
|
||||
|
||||
/* ---- au-3 (pin 2vh): Strong Resources -> zoom + logo ---- */
|
||||
if (s3) {
|
||||
var q = clamp((window.scrollY - start3) / vh, 0, 2);
|
||||
var t = clamp((q - 1.0) / 1.0, 0, 1);
|
||||
|
||||
// head (screen 3): held first screen, fades second
|
||||
if (head) head.style.opacity = String(clamp(1 - (q - 0.6) / 0.3, 0, 1));
|
||||
// zoom: scale to fullscreen; photo opacity stays 1 — a black veil fades in over it
|
||||
if (zoom) {
|
||||
zoom.style.transform = 'translate(-50%, -50%) scale(' + lerp(1, 2.2, t).toFixed(3) + ')';
|
||||
}
|
||||
if (zoomMask) zoomMask.style.opacity = String(lerp(0, 0.8, t).toFixed(3));
|
||||
// reveal (screen 4): logo+text in second screen
|
||||
if (reveal) reveal.style.opacity = String(clamp((q - 1.1) / 0.4, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
var ticking = false;
|
||||
function onScroll() {
|
||||
if (ticking) return;
|
||||
ticking = true;
|
||||
requestAnimationFrame(function () { update(); ticking = false; });
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', onScroll, { passive: true });
|
||||
window.addEventListener('resize', function () { measure(); onScroll(); });
|
||||
measure();
|
||||
update();
|
||||
})();
|
||||
|
||||
/* ============================================================
|
||||
GPS data carousel — auto-rotate + dot navigation
|
||||
============================================================ */
|
||||
(function () {
|
||||
var track = document.querySelector('.au-gps__track');
|
||||
var dotsWrap = document.querySelector('.au-gps__dots');
|
||||
if (!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() { timer = setInterval(next, 4000); }
|
||||
function restart() { clearInterval(timer); start(); }
|
||||
|
||||
render();
|
||||
start();
|
||||
// pause auto-rotate while hovering
|
||||
track.addEventListener('mouseenter', function () { clearInterval(timer); });
|
||||
track.addEventListener('mouseleave', start);
|
||||
})();
|
||||
Reference in New Issue
Block a user