update
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
// Mitte schiebt man das ganze Fenster. Daneben zieht man den Strahl
|
||||
// selbst nach links und rechts. Zeiten in Sekunden relativ zur Marke:
|
||||
// 0 ist der Moment, an dem C gedrückt wurde.
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
// Stücke der Aufnahme: [{ von, bis }] relativ zur Marke
|
||||
@@ -83,9 +83,27 @@ function uhrzeit(t) {
|
||||
// ── Ziehen ────────────────────────────────────────────────────────────
|
||||
let griff = null
|
||||
let ausgang = null
|
||||
// Ob sich die Hand seit dem Anfassen bewegt hat — sonst war es ein Klick
|
||||
let bewegt = false
|
||||
|
||||
function zeitBei(clientX) {
|
||||
const box = strahl.value.getBoundingClientRect()
|
||||
return links.value + ((clientX - box.left) / box.width) * spanne.value
|
||||
}
|
||||
|
||||
// Das Fenster an eine Stelle setzen: sein Anfang liegt dort, es bleibt im Stück
|
||||
function setzen(t) {
|
||||
const g = stueckUm(t)
|
||||
const d = Math.max(props.minDauer, Math.min(dauer.value, g.bis - g.von))
|
||||
const s = Math.max(g.von, Math.min(g.bis - d, t))
|
||||
vorher.value = Math.round(-s)
|
||||
dauer.value = Math.round(d)
|
||||
emit('ende')
|
||||
}
|
||||
|
||||
function anfassen(e, was) {
|
||||
griff = was
|
||||
bewegt = false
|
||||
ausgang = {
|
||||
x: e.clientX,
|
||||
vorher: vorher.value,
|
||||
@@ -100,6 +118,7 @@ function anfassen(e, was) {
|
||||
function ziehen(e) {
|
||||
if (!griff || !strahl.value) return
|
||||
const dt = ((e.clientX - ausgang.x) / strahl.value.clientWidth) * spanne.value
|
||||
if (Math.abs(e.clientX - ausgang.x) > 4) bewegt = true
|
||||
const g = ausgang.stueck
|
||||
if (griff === 'bahn') {
|
||||
// Den Strahl selbst schieben — die Zeiten laufen der Hand entgegen
|
||||
@@ -134,9 +153,46 @@ function loslassen(e) {
|
||||
const war = griff
|
||||
griff = null
|
||||
e.currentTarget.releasePointerCapture?.(e.pointerId)
|
||||
// Nur ein verändertes Fenster braucht eine neue Vorschau
|
||||
if (war !== 'bahn') emit('ende')
|
||||
if (war === 'bahn') {
|
||||
// Ein Klick ohne Ziehen setzt das Fenster hierhin; Schieben braucht keine neue Vorschau
|
||||
if (!bewegt) setzen(zeitBei(e.clientX))
|
||||
return
|
||||
}
|
||||
emit('ende')
|
||||
}
|
||||
|
||||
// Mausrad: zoomen, der Punkt unter dem Zeiger bleibt stehen
|
||||
function rad(e) {
|
||||
const neu = Math.max(0, Math.min(ZOOMS.length - 1, zoom.value + (e.deltaY > 0 ? 1 : -1)))
|
||||
if (neu === zoom.value || !strahl.value) return
|
||||
const box = strahl.value.getBoundingClientRect()
|
||||
const anteil = (e.clientX - box.left) / box.width
|
||||
const t = links.value + anteil * spanne.value
|
||||
zoom.value = neu
|
||||
const r = grenzen.value
|
||||
mitte.value = Math.max(r.von, Math.min(r.bis, t - (anteil - 0.5) * ZOOMS[neu]))
|
||||
}
|
||||
|
||||
// Pfeiltasten: 1 s, mit Shift 10 s. Die Vorschau lädt erst, wenn Ruhe ist
|
||||
let tastenTimer = null
|
||||
|
||||
function taste(e) {
|
||||
if (e.target instanceof Element && e.target.matches('input, textarea')) return
|
||||
if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') return
|
||||
e.preventDefault()
|
||||
const schritt = (e.shiftKey ? 10 : 1) * (e.key === 'ArrowLeft' ? -1 : 1)
|
||||
const g = stueckUm(start.value + dauer.value / 2)
|
||||
const s = Math.max(g.von, Math.min(g.bis - dauer.value, start.value + schritt))
|
||||
vorher.value = Math.round(-s)
|
||||
clearTimeout(tastenTimer)
|
||||
tastenTimer = setTimeout(() => emit('ende'), 400)
|
||||
}
|
||||
|
||||
onMounted(() => window.addEventListener('keydown', taste))
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('keydown', taste)
|
||||
clearTimeout(tastenTimer)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -162,6 +218,7 @@ function loslassen(e) {
|
||||
ref="strahl"
|
||||
class="strahl"
|
||||
@pointerdown="anfassen($event, 'bahn')"
|
||||
@wheel.prevent="rad"
|
||||
@pointermove="ziehen"
|
||||
@pointerup="loslassen"
|
||||
@pointercancel="loslassen"
|
||||
@@ -257,6 +314,8 @@ function loslassen(e) {
|
||||
.bereich {
|
||||
position: absolute;
|
||||
top: 0.4rem;
|
||||
/* Bei vier Stunden Ansicht wäre das Fenster ein Strich — so bleibt es greifbar */
|
||||
min-width: 2.2rem;
|
||||
height: 1.6rem;
|
||||
background: rgba(229, 9, 20, 0.35);
|
||||
border: 2px solid var(--accent);
|
||||
|
||||
Reference in New Issue
Block a user