diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 6c5b9ae..60774fa 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -225,6 +225,32 @@ const tabs = computed(() => [ const rad = ref(null) +// Bei 2500 Karten kommt man sonst nicht mehr nach oben +const obenKnopf = ref(false) + +function beimScrollen() { + obenKnopf.value = window.scrollY > 800 +} + +// Eigene Animation statt behavior: 'smooth'. Das rechnet mit fester +// Geschwindigkeit und bräuchte über 300.000 Pixel Seitenhöhe Minuten. +const OBEN_DAUER = 450 + +function nachOben() { + const start = window.scrollY + const beginn = performance.now() + + function schritt(jetzt) { + const t = Math.min(1, (jetzt - beginn) / OBEN_DAUER) + // Sanft an- und auslaufend + const p = t < 0.5 ? 2 * t * t : 1 - (-2 * t + 2) ** 2 / 2 + window.scrollTo(0, start * (1 - p)) + if (t < 1) requestAnimationFrame(schritt) + } + + requestAnimationFrame(schritt) +} + // Die movie_ids der geschauten Filme — die Detailansicht zeigt damit an, // ob der Film schon lief const gesehen = ref([]) @@ -476,10 +502,12 @@ onMounted(() => { else if (nachricht.type === 'features') ladeWuensche() }) window.addEventListener('keydown', tastatur) + window.addEventListener('scroll', beimScrollen, { passive: true }) }) onUnmounted(() => { window.removeEventListener('keydown', tastatur) + window.removeEventListener('scroll', beimScrollen) abbestellen?.() }) @@ -594,6 +622,10 @@ onUnmounted(() => { /> + + { } .tabs { + position: sticky; + top: 0; + z-index: 10; display: flex; gap: 0.35rem; - margin-bottom: 1.25rem; + /* Der negative Rand deckt das Polster der Seite ab, sonst scrollen + Karten oberhalb der Leiste durchs Bild */ + margin: -1.5rem -1.25rem 1.25rem; + padding: 0.7rem 1.25rem 0; + background: var(--bg); border-bottom: 1px solid var(--line); } +.nach-oben { + position: fixed; + right: calc(var(--sidebar) + 1.25rem); + bottom: 1.5rem; + z-index: 15; + width: 3rem; + height: 3rem; + color: #fff; + font-size: 1.35rem; + line-height: 1; + background: var(--accent); + border: 0; + border-radius: 50%; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6); +} + +.nach-oben:hover { + filter: brightness(1.15); +} + .tabs button { display: flex; align-items: center;