Motion blur while scrolling.
This commit is contained in:
@@ -46,6 +46,26 @@ const viewportHeight = ref(600)
|
||||
const rowHeight = ref(64)
|
||||
const rowProbe = ref(null)
|
||||
let rowProbeObserver = null
|
||||
|
||||
// Scrolling blur effect
|
||||
const blurAmount = ref(0) // pixels
|
||||
let _lastBlurPos = 0
|
||||
let _blurFrame = null
|
||||
|
||||
function _updateMotionBlur() {
|
||||
const pos = scrollTop.value || 0
|
||||
if (_lastBlurPos) {
|
||||
blurAmount.value = 0.5 * Math.abs(pos - _lastBlurPos)
|
||||
}
|
||||
_lastBlurPos = pos
|
||||
_blurFrame = requestAnimationFrame(_updateMotionBlur)
|
||||
}
|
||||
|
||||
const viewportBlurStyle = computed(() => {
|
||||
return blurAmount.value > 0
|
||||
? { filter: 'url(#cal-vert-blur)', willChange: 'filter' }
|
||||
: { filter: 'none' }
|
||||
})
|
||||
const baseDate = computed(() => new Date(1970, 0, 4 + calendarStore.config.first_day))
|
||||
const selection = ref({ startDate: null, dayCount: 0 })
|
||||
const isDragging = ref(false)
|
||||
@@ -387,6 +407,10 @@ onMounted(() => {
|
||||
onBeforeUnmount(() => {
|
||||
clearInterval(timer)
|
||||
})
|
||||
|
||||
// Start motion blur loop
|
||||
_lastBlurPos = scrollTop.value || 0
|
||||
_blurFrame = requestAnimationFrame(_updateMotionBlur)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
@@ -403,6 +427,7 @@ onBeforeUnmount(() => {
|
||||
}
|
||||
}
|
||||
document.removeEventListener('pointerlockchange', handlePointerLockChange)
|
||||
if (_blurFrame) cancelAnimationFrame(_blurFrame)
|
||||
})
|
||||
|
||||
const handleDayMouseDown = (d) => {
|
||||
@@ -506,6 +531,15 @@ window.addEventListener('resize', () => {
|
||||
<template>
|
||||
<div class="calendar-view-root" :dir="rtl && 'rtl'">
|
||||
<div ref="rowProbe" class="row-height-probe" aria-hidden="true"></div>
|
||||
<!-- Inline SVG filter for vertical motion blur -->
|
||||
<svg width="0" height="0" aria-hidden="true" focusable="false" class="motion-blur-defs">
|
||||
<defs>
|
||||
<!-- stdDeviation: x y; keep a tiny epsilon on X so some browsers don't drop the filter entirely -->
|
||||
<filter id="cal-vert-blur" color-interpolation-filters="sRGB" x="-10%" width="120%" y="-10%" height="120%">
|
||||
<feGaussianBlur :stdDeviation="`${0.001} ${blurAmount.toFixed(2)}`" edgeMode="duplicate" />
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
<div class="wrap">
|
||||
<HeaderControls
|
||||
:reference-date="centerVisibleDateStr"
|
||||
@@ -520,7 +554,7 @@ window.addEventListener('resize', () => {
|
||||
@year-change="handleHeaderYearChange"
|
||||
/>
|
||||
<div class="calendar-container">
|
||||
<div class="calendar-viewport" ref="viewport">
|
||||
<div class="calendar-viewport" ref="viewport" :style="viewportBlurStyle">
|
||||
<div class="calendar-content" :style="{ height: contentHeight + 'px' }">
|
||||
<div
|
||||
class="weeks-wrapper"
|
||||
|
||||
Reference in New Issue
Block a user