commit 42e88ef3013d46065add010e05576766ec1f9482
parent e0108411fee7f6fc172f9794dd30a30019242df1
Author: Hunter
Date: Tue, 1 Apr 2025 00:03:08 -0400
add inertial scrolling.
Diffstat:
| M | index.html | | | 77 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 77 insertions(+), 0 deletions(-)
diff --git a/index.html b/index.html
@@ -261,6 +261,10 @@
}
});
document.addEventListener('DOMContentLoaded', function() {
+ // Variables for scroll handling
+ let lastScrollPosition = 0;
+ let isScrolling = false;
+ let scrollDebounceTimer;
const appContainer = document.getElementById('app-container');
let rootTask = loadTasksFromLocalStorage();
let currentTask = rootTask;
@@ -1093,6 +1097,79 @@
document.addEventListener('keydown', handleSave);
document.addEventListener('keydown', handleOpen);
+
+ // Add scroll handling to navigate tasks with inertia
+ window.addEventListener('wheel', handleScroll, { passive: false });
+
+ // Scroll inertia implementation
+ const scrollState = {
+ momentum: 0,
+ isAnimating: false,
+ lastScrollTime: Date.now(),
+ scrollAccumulator: 0,
+ taskNavigationThreshold: 250 // Pixels needed to move one task
+ };
+
+ function handleScroll(e) {
+ // Prevent the default scroll behavior
+ e.preventDefault();
+
+ // Get scroll delta and update time
+ const now = Date.now();
+ const timeDelta = now - scrollState.lastScrollTime;
+ scrollState.lastScrollTime = now;
+
+ // Calculate momentum (higher for faster scrolls)
+ const rawDelta = e.deltaY || e.detail || -e.wheelDelta;
+ const delta = Math.sign(rawDelta) * Math.min(Math.abs(rawDelta), 100); // Cap delta
+
+ // Add to momentum based on time between scrolls (faster scrolls = more momentum)
+ if (timeDelta < 100) {
+ // Rapid scrolling gets more momentum
+ scrollState.momentum += delta * (1 + (100 - timeDelta) / 100);
+ } else {
+ // Slower scrolling gets normal momentum
+ scrollState.momentum += delta;
+ }
+
+ // Start animation if not already running
+ if (!scrollState.isAnimating) {
+ scrollState.isAnimating = true;
+ animateMomentumScroll();
+ }
+ }
+
+ function animateMomentumScroll() {
+ // If momentum is close to zero, stop animation
+ if (Math.abs(scrollState.momentum) < 0.5) {
+ scrollState.momentum = 0;
+ scrollState.isAnimating = false;
+ return;
+ }
+
+ // Add momentum to accumulator
+ scrollState.scrollAccumulator += scrollState.momentum;
+
+ // Check if we've crossed the threshold to move tasks
+ if (Math.abs(scrollState.scrollAccumulator) >= scrollState.taskNavigationThreshold) {
+ const tasksToMove = Math.floor(Math.abs(scrollState.scrollAccumulator) / scrollState.taskNavigationThreshold);
+ const direction = scrollState.scrollAccumulator > 0 ? 'down' : 'up';
+
+ // Move the specified number of tasks
+ for (let i = 0; i < tasksToMove; i++) {
+ navigateTasks(direction);
+ }
+
+ // Remove the used part from accumulator
+ scrollState.scrollAccumulator = scrollState.scrollAccumulator % scrollState.taskNavigationThreshold;
+ }
+
+ // Apply friction to slow down momentum (adjust factor for feel)
+ scrollState.momentum *= 0.6;
+
+ // Continue animation
+ requestAnimationFrame(animateMomentumScroll);
+ }
getThemesFromCSS();
setInitialTheme();