fixed dogshit scroll

This commit is contained in:
2026-02-06 15:22:05 +00:00
parent 56ae7f3760
commit 0137f158b4

View File

@@ -1,117 +1,45 @@
<script setup>
import { ref, onMounted, onBeforeUnmount, watchEffect } from "vue";
const container = ref(null);
const direction = ref(1); // 1 = down, -1 = up
const isPaused = ref(false);
const animationFrameId = ref(null);
const lastTime = ref(0);
const SPEED = 0.03; // px per ms (better for frame rate independence)
const PAUSE_DURATION = 2000; // ms at top/bottom
// Use requestAnimationFrame for smoother scrolling
function scrollStep(timestamp) {
if (isPaused.value) return;
if (!lastTime.value) lastTime.value = timestamp;
const deltaTime = timestamp - lastTime.value;
lastTime.value = timestamp;
if (!container.value) return;
const el = container.value;
const scrollDistance = SPEED * deltaTime * direction.value;
el.scrollTop += scrollDistance;
const reachedBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 1;
const reachedTop = el.scrollTop <= 1;
if (reachedBottom || reachedTop) {
direction.value *= -1;
isPaused.value = true;
setTimeout(() => {
isPaused.value = false;
if (!isPaused.value) {
animationFrameId.value = requestAnimationFrame(scrollStep);
}
}, PAUSE_DURATION);
return;
}
animationFrameId.value = requestAnimationFrame(scrollStep);
}
function pauseScroll() {
isPaused.value = true;
lastTime.value = 0; // Reset time tracking
}
function resumeScroll() {
if (isPaused.value) {
isPaused.value = false;
animationFrameId.value = requestAnimationFrame(scrollStep);
}
}
function startScrolling() {
if (!isPaused.value) {
animationFrameId.value = requestAnimationFrame(scrollStep);
}
}
function stopScrolling() {
if (animationFrameId.value) {
cancelAnimationFrame(animationFrameId.value);
animationFrameId.value = null;
}
}
onMounted(() => {
startScrolling();
});
onBeforeUnmount(() => {
stopScrolling();
});
// Optional: Auto-pause when component is not visible
const observer = ref(null);
onMounted(() => {
if ("IntersectionObserver" in window) {
observer.value = new IntersectionObserver(
(entries) => {
isPaused.value = !entries[0].isIntersecting;
if (!isPaused.value) {
startScrolling();
}
},
{ threshold: 0.1 },
);
if (container.value) {
observer.value.observe(container.value);
}
}
});
onBeforeUnmount(() => {
if (observer.value) {
observer.value.disconnect();
}
});
</script>
<template>
<div
ref="container"
@mouseover="pauseScroll"
@mouseleave="resumeScroll"
class="overflow-y-auto"
>
<div ref="container" @mouseover="handleHover" class="overflow-y-auto">
<slot />
</div>
</template>
<script setup>
import { useTemplateRef, onMounted, onBeforeUnmount } from "vue";
const container = useTemplateRef("container");
const SPEED = 1; // px per frame
const PAUSE = 2000; // ms at top/bottom
const FRAME_TIME = 50; // ms at top/bottom
let direction = 1; // 1 = down, -1 = up
let timeoutId;
function handleHover() {
cancelAnimationFrame(timeoutId);
setTimeout(() => requestAnimationFrame(tick), PAUSE);
}
function tick() {
const el = container.value;
el.scrollTop += SPEED * direction;
const reachedBottom = el.scrollTop + el.clientHeight >= el.scrollHeight;
const reachedTop = el.scrollTop <= 0;
if (reachedBottom || reachedTop) {
direction *= -1;
}
timeoutId = requestAnimationFrame(tick);
}
onMounted(() => {
timeoutId = requestAnimationFrame(tick);
});
onBeforeUnmount(() => {
cancelAnimationFrame(timeoutId);
});
</script>