feat: portfolio-led redesign with Shootings umbrella, original logo and motion layer
This commit is contained in:
@@ -69,20 +69,106 @@
|
||||
});
|
||||
}
|
||||
|
||||
/* Soft reveal on scroll, disabled for reduced motion */
|
||||
/* Motion layer: reveals, scroll progress, parallax and pointer spotlights.
|
||||
Everything degrades to a static page and is disabled for reduced motion. */
|
||||
var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
/* Anything inside [data-stagger] reveals one item after another. */
|
||||
Array.prototype.forEach.call(document.querySelectorAll('[data-stagger]'), function (group) {
|
||||
var step = parseFloat(group.getAttribute('data-stagger')) || 0.08;
|
||||
Array.prototype.forEach.call(group.children, function (child, index) {
|
||||
if (!child.classList.contains('reveal')) {
|
||||
child.classList.add('reveal');
|
||||
}
|
||||
child.style.setProperty('--d', (index * step).toFixed(2) + 's');
|
||||
});
|
||||
});
|
||||
|
||||
var items = document.querySelectorAll('.reveal');
|
||||
var revealAll = function () {
|
||||
Array.prototype.forEach.call(items, function (item) { item.classList.add('is-in'); });
|
||||
};
|
||||
if (reduce || !('IntersectionObserver' in window)) {
|
||||
items.forEach(function (item) { item.classList.add('is-in'); });
|
||||
revealAll();
|
||||
} else {
|
||||
var observer = new IntersectionObserver(function (entries) {
|
||||
entries.forEach(function (entry) {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('is-in');
|
||||
observer.unobserve(entry.target);
|
||||
try {
|
||||
var fired = 0;
|
||||
var observer = new IntersectionObserver(function (entries) {
|
||||
entries.forEach(function (entry) {
|
||||
if (entry.isIntersecting) {
|
||||
fired = 1;
|
||||
entry.target.classList.add('is-in');
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, { rootMargin: '0px 0px -8% 0px', threshold: 0.06 });
|
||||
Array.prototype.forEach.call(items, function (item) { observer.observe(item); });
|
||||
/* Safety net: if the browser never reports a box that is on screen, drop the
|
||||
effect entirely instead of leaving content hidden. */
|
||||
window.setTimeout(function () {
|
||||
if (fired) { return; }
|
||||
var onScreen = false;
|
||||
Array.prototype.forEach.call(items, function (item) {
|
||||
var box = item.getBoundingClientRect();
|
||||
if (box.top < window.innerHeight && box.bottom > 0) { onScreen = true; }
|
||||
});
|
||||
if (onScreen) {
|
||||
observer.disconnect();
|
||||
revealAll();
|
||||
}
|
||||
});
|
||||
}, { rootMargin: '0px 0px -10% 0px', threshold: 0.05 });
|
||||
items.forEach(function (item) { observer.observe(item); });
|
||||
}, 1600);
|
||||
} catch (error) {
|
||||
revealAll();
|
||||
}
|
||||
}
|
||||
|
||||
if (reduce) {
|
||||
return;
|
||||
}
|
||||
|
||||
var progress = document.querySelector('[data-progress]');
|
||||
var parallax = Array.prototype.slice.call(document.querySelectorAll('[data-parallax]'));
|
||||
var ticking = false;
|
||||
|
||||
function onScroll() {
|
||||
var doc = document.documentElement;
|
||||
var max = doc.scrollHeight - window.innerHeight;
|
||||
var ratio = max > 0 ? Math.min(1, Math.max(0, window.scrollY / max)) : 0;
|
||||
if (progress) {
|
||||
progress.style.setProperty('--scroll', ratio.toFixed(4));
|
||||
}
|
||||
if (parallax.length) {
|
||||
var view = window.innerHeight;
|
||||
parallax.forEach(function (element) {
|
||||
var rect = element.getBoundingClientRect();
|
||||
if (rect.bottom < -240 || rect.top > view + 240) {
|
||||
return;
|
||||
}
|
||||
var speed = parseFloat(element.getAttribute('data-parallax')) || 0.12;
|
||||
var offset = (rect.top + rect.height / 2 - view / 2) * speed;
|
||||
element.style.setProperty('--py', offset.toFixed(1) + 'px');
|
||||
});
|
||||
}
|
||||
ticking = false;
|
||||
}
|
||||
|
||||
function requestScroll() {
|
||||
if (!ticking) {
|
||||
ticking = true;
|
||||
window.requestAnimationFrame(onScroll);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', requestScroll, { passive: true });
|
||||
window.addEventListener('resize', requestScroll);
|
||||
onScroll();
|
||||
|
||||
/* Pointer-following highlight on the media cards. */
|
||||
Array.prototype.forEach.call(document.querySelectorAll('.spot'), function (card) {
|
||||
card.addEventListener('pointermove', function (event) {
|
||||
var rect = card.getBoundingClientRect();
|
||||
card.style.setProperty('--mx', ((event.clientX - rect.left) / rect.width * 100).toFixed(1) + '%');
|
||||
card.style.setProperty('--my', ((event.clientY - rect.top) / rect.height * 100).toFixed(1) + '%');
|
||||
});
|
||||
});
|
||||
}());
|
||||
|
||||
Reference in New Issue
Block a user