new components and stamps
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div ref="container" class="overflow-y-auto">
|
||||
<div ref="container" @mouseover="handleHover" class="overflow-y-auto">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
@@ -14,38 +14,37 @@ const PAUSE = 2000; // ms at top/bottom
|
||||
const FRAME_TIME = 50; // ms at top/bottom
|
||||
|
||||
let direction = 1; // 1 = down, -1 = up
|
||||
let paused = false;
|
||||
let rafId;
|
||||
let timeoutId;
|
||||
|
||||
function handleHover() {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(tick, PAUSE);
|
||||
}
|
||||
|
||||
function tick() {
|
||||
const el = container.value;
|
||||
|
||||
el.scrollTop += SPEED * direction;
|
||||
|
||||
const reachedBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 1;
|
||||
const reachedBottom = el.scrollTop + el.clientHeight >= el.scrollHeight;
|
||||
const reachedTop = el.scrollTop <= 0;
|
||||
|
||||
if (reachedBottom || reachedTop) {
|
||||
direction *= -1;
|
||||
|
||||
timeoutId = setTimeout(() => {
|
||||
paused = false;
|
||||
rafId = setTimeout(tick, FRAME_TIME);
|
||||
}, PAUSE);
|
||||
timeoutId = setTimeout(tick, PAUSE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
rafId = setTimeout(tick, FRAME_TIME);
|
||||
timeoutId = setTimeout(tick, FRAME_TIME);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
rafId = setTimeout(tick, FRAME_TIME);
|
||||
timeoutId = setTimeout(tick, FRAME_TIME);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
clearTimeout(rafId);
|
||||
clearTimeout(timeoutId);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -67,9 +67,9 @@ function playFinishedSound() {
|
||||
>
|
||||
<h2 class="items-center">Timer</h2>
|
||||
<div v-if="finished && paused" class="flex flex-col">
|
||||
<div class="flex flex-row p-2">
|
||||
<div class="flex flex-row p-2 place-content-around">
|
||||
<input
|
||||
class="w-full"
|
||||
class="w-2/3"
|
||||
v-model="minutesInput"
|
||||
type="range"
|
||||
min="0"
|
||||
@@ -77,9 +77,9 @@ function playFinishedSound() {
|
||||
/>
|
||||
<p>{{ minutesInput }}m</p>
|
||||
</div>
|
||||
<div class="flex flex-row p-2">
|
||||
<div class="flex flex-row p-2 place-content-around">
|
||||
<input
|
||||
class="w-full"
|
||||
class="w-2/3"
|
||||
v-model="secondsInput"
|
||||
type="range"
|
||||
min="0"
|
||||
|
||||
67
nginx/vue/src/components/util/Touchscreen.vue
Normal file
67
nginx/vue/src/components/util/Touchscreen.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div
|
||||
ref="container"
|
||||
class="overflow-auto w-full h-full"
|
||||
@mousedown="handleMouseDown"
|
||||
@mousemove="handleMouseMove"
|
||||
@mouseup="handleMouseUp"
|
||||
@mouseleave="handleMouseLeave"
|
||||
:style="{ cursor: isDragging ? 'grabbing' : 'grab' }"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
|
||||
const container = ref(null);
|
||||
const isDragging = ref(false);
|
||||
const startX = ref(0);
|
||||
const startY = ref(0);
|
||||
const scrollLeft = ref(0);
|
||||
const scrollTop = ref(0);
|
||||
|
||||
const handleMouseDown = (e) => {
|
||||
isDragging.value = true;
|
||||
startX.value = e.pageX - container.value.offsetLeft;
|
||||
startY.value = e.pageY - container.value.offsetTop;
|
||||
scrollLeft.value = container.value.scrollLeft;
|
||||
scrollTop.value = container.value.scrollTop;
|
||||
|
||||
// Prevent text selection while dragging
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
const handleMouseMove = (e) => {
|
||||
if (!isDragging.value) return;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
const x = e.pageX - container.value.offsetLeft;
|
||||
const y = e.pageY - container.value.offsetTop;
|
||||
const walkX = (x - startX.value) * 1; // Multiply by scroll speed factor
|
||||
const walkY = (y - startY.value) * 1;
|
||||
|
||||
container.value.scrollLeft = scrollLeft.value - walkX;
|
||||
container.value.scrollTop = scrollTop.value - walkY;
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
isDragging.value = false;
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
isDragging.value = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Prevent text selection while dragging */
|
||||
div[style*="cursor: grabbing"] {
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user