105 lines
2.8 KiB
JavaScript
105 lines
2.8 KiB
JavaScript
|
|
// edge-scroll.js - med timeout + tidsbaseret scroll
|
||
|
|
(function() {
|
||
|
|
'use strict';
|
||
|
|
|
||
|
|
const OUTER_ZONE = 100; // px fra kant (langsom zone)
|
||
|
|
const INNER_ZONE = 50; // px fra kant (hurtig zone)
|
||
|
|
const SLOW_SPEED_PXS = 800; // px/sek i outer zone
|
||
|
|
const FAST_SPEED_PXS = 2400; // px/sek i inner zone
|
||
|
|
|
||
|
|
let scrollableContent = null;
|
||
|
|
let scrollRAF = null;
|
||
|
|
let mouseY = 0;
|
||
|
|
let haveMouse = false;
|
||
|
|
let lastTs = 0;
|
||
|
|
let rect = null;
|
||
|
|
|
||
|
|
function init() {
|
||
|
|
console.log('edge-scroll.js: waiting 1000ms before setup...');
|
||
|
|
setTimeout(setup, 1000);
|
||
|
|
}
|
||
|
|
|
||
|
|
function setup() {
|
||
|
|
console.log('edge-scroll.js: setup() called');
|
||
|
|
|
||
|
|
scrollableContent = document.querySelector('swp-scrollable-content');
|
||
|
|
if (!scrollableContent) {
|
||
|
|
console.error('edge-scroll.js: swp-scrollable-content NOT FOUND');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log('edge-scroll.js: found scrollableContent:', scrollableContent);
|
||
|
|
|
||
|
|
// slå smooth scroll fra, så autoscroll er øjeblikkelig
|
||
|
|
scrollableContent.style.scrollBehavior = 'auto';
|
||
|
|
|
||
|
|
scrollableContent.addEventListener('mousemove', handleMouseMove, { passive: true });
|
||
|
|
scrollableContent.addEventListener('mouseleave', handleMouseLeave, { passive: true });
|
||
|
|
|
||
|
|
console.log('edge-scroll.js: ✅ listeners attached');
|
||
|
|
}
|
||
|
|
|
||
|
|
function handleMouseMove(e) {
|
||
|
|
haveMouse = true;
|
||
|
|
mouseY = e.clientY;
|
||
|
|
if (scrollRAF == null) {
|
||
|
|
lastTs = performance.now();
|
||
|
|
scrollRAF = requestAnimationFrame(scrollTick);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function handleMouseLeave() {
|
||
|
|
haveMouse = false;
|
||
|
|
stopScrolling();
|
||
|
|
}
|
||
|
|
|
||
|
|
function stopScrolling() {
|
||
|
|
if (scrollRAF != null) {
|
||
|
|
cancelAnimationFrame(scrollRAF);
|
||
|
|
scrollRAF = null;
|
||
|
|
}
|
||
|
|
lastTs = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
function scrollTick(ts) {
|
||
|
|
const dt = lastTs ? (ts - lastTs) / 1000 : 0;
|
||
|
|
lastTs = ts;
|
||
|
|
|
||
|
|
if (!rect) rect = scrollableContent.getBoundingClientRect();
|
||
|
|
|
||
|
|
let vy = 0;
|
||
|
|
if (haveMouse) {
|
||
|
|
const distTop = mouseY - rect.top;
|
||
|
|
const distBot = rect.bottom - mouseY;
|
||
|
|
|
||
|
|
// Check top edge
|
||
|
|
if (distTop < INNER_ZONE) {
|
||
|
|
// Inner zone (0-50px) - fast speed
|
||
|
|
vy = -FAST_SPEED_PXS;
|
||
|
|
} else if (distTop < OUTER_ZONE) {
|
||
|
|
// Outer zone (50-100px) - slow speed
|
||
|
|
vy = -SLOW_SPEED_PXS;
|
||
|
|
}
|
||
|
|
// Check bottom edge
|
||
|
|
else if (distBot < INNER_ZONE) {
|
||
|
|
// Inner zone (0-50px) - fast speed
|
||
|
|
vy = FAST_SPEED_PXS;
|
||
|
|
} else if (distBot < OUTER_ZONE) {
|
||
|
|
// Outer zone (50-100px) - slow speed
|
||
|
|
vy = SLOW_SPEED_PXS;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (vy !== 0) {
|
||
|
|
scrollableContent.scrollTop += vy * dt;
|
||
|
|
rect = null; // mål kun én gang pr. frame
|
||
|
|
scrollRAF = requestAnimationFrame(scrollTick);
|
||
|
|
} else {
|
||
|
|
stopScrolling();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// start init
|
||
|
|
init();
|
||
|
|
})();
|