57 lines
1.4 KiB
JavaScript
57 lines
1.4 KiB
JavaScript
let treeOriginalTop = null;
|
|
let currentVelocity = 0;
|
|
let isAnimating = false;
|
|
|
|
window.addEventListener('wheel', (e) => {
|
|
if(window.innerWidth < 600) {
|
|
return;
|
|
}
|
|
|
|
// Add scroll delta to the velocity
|
|
currentVelocity += e.deltaY;
|
|
|
|
// Start animation loop if not running
|
|
if (!isAnimating) {
|
|
isAnimating = true;
|
|
requestAnimationFrame(animateScroll);
|
|
}
|
|
}, { passive: false });
|
|
|
|
function animateScroll() {
|
|
const tree = document.getElementById("tree");
|
|
|
|
if (!treeOriginalTop) {
|
|
treeOriginalTop = parseInt(getComputedStyle(tree).top);
|
|
}
|
|
|
|
const treeHeightPX = 0.83 * window.innerHeight;
|
|
let treeTopPX = parseInt(getComputedStyle(tree).top);
|
|
|
|
// Limit per-frame speed (but NOT total speed)
|
|
let multiplier = window.innerHeight / 2000;
|
|
let delta = Math.max(-100 * multiplier, Math.min(100 * multiplier, currentVelocity));
|
|
|
|
// Apply the scroll
|
|
let newTop = treeTopPX - delta;
|
|
|
|
// Clamp top/bottom bounds
|
|
const maxTop = treeOriginalTop;
|
|
const minTop = treeOriginalTop - treeHeightPX;
|
|
|
|
if (newTop > maxTop) newTop = maxTop;
|
|
if (newTop < minTop) newTop = minTop;
|
|
|
|
tree.style.top = `${newTop}px`;
|
|
|
|
// Slowly reduce velocity
|
|
currentVelocity *= 0.85;
|
|
|
|
// If velocity is small, stop
|
|
if (Math.abs(currentVelocity) > 0.5) {
|
|
requestAnimationFrame(animateScroll);
|
|
} else {
|
|
isAnimating = false;
|
|
currentVelocity = 0;
|
|
}
|
|
}
|