Refactor jogwheel to its own module.

This commit is contained in:
2025-08-21 09:38:28 +00:00
parent f9f8cceb07
commit e4c960b0ca
2 changed files with 85 additions and 30 deletions
+6 -30
View File
@@ -15,6 +15,7 @@ import {
lunarPhaseSymbol
} from './date-utils.js'
import { EventManager } from './event-manager.js'
import { JogwheelManager } from './jogwheel.js'
class InfiniteCalendar {
constructor(config = {}) {
@@ -33,10 +34,11 @@ class InfiniteCalendar {
this.viewport = document.getElementById('calendar-viewport')
this.content = document.getElementById('calendar-content')
this.header = document.getElementById('calendar-header')
this.jogwheelViewport = document.getElementById('jogwheel-viewport')
this.jogwheelContent = document.getElementById('jogwheel-content')
this.selectedDateInput = document.getElementById('selected-date')
// Initialize jogwheel manager after DOM elements are available
this.jogwheelManager = new JogwheelManager(this)
this.rowHeight = this.computeRowHeight()
this.visibleWeeks = new Map()
this.baseDate = new Date(2024, 0, 1) // 2024 begins with Monday
@@ -45,7 +47,6 @@ class InfiniteCalendar {
} init() {
this.createHeader()
this.setupScrollListener()
this.setupJogwheel()
this.setupYearScroll()
this.setupSelectionInput()
this.setupCurrentDate()
@@ -63,7 +64,7 @@ class InfiniteCalendar {
this.totalVirtualWeeks = this.maxVirtualWeek - this.minVirtualWeek + 1
this.content.style.height = `${this.totalVirtualWeeks * this.rowHeight}px`
this.jogwheelContent.style.height = `${(this.totalVirtualWeeks * this.rowHeight) / 10}px`
this.jogwheelManager.updateHeight(this.totalVirtualWeeks, this.rowHeight)
const initial = this.config.initial || this.today
this.navigateTo(fromLocalString(initial))
}
@@ -149,11 +150,7 @@ class InfiniteCalendar {
else this.viewport.scrollTop = targetScrollTop
const mainScrollable = Math.max(0, this.content.scrollHeight - this.viewport.clientHeight)
const jogScrollable = Math.max(0, this.jogwheelContent.scrollHeight - this.jogwheelViewport.clientHeight)
const jogwheelTarget = mainScrollable > 0 ? (targetScrollTop / mainScrollable) * jogScrollable : 0
if (smooth) this.jogwheelViewport.scrollTo({ top: jogwheelTarget, behavior: 'smooth' })
else this.jogwheelViewport.scrollTop = jogwheelTarget
this.jogwheelManager.scrollTo(targetScrollTop, mainScrollable, smooth)
if (forceUpdate) this.updateVisibleWeeks()
return true
@@ -415,27 +412,6 @@ class InfiniteCalendar {
return weekDiv
}
setupJogwheel() {
let lock = null
const sync = (fromEl, toEl, fromContent, toContent) => {
if (lock === toEl) return
lock = fromEl
const fromScrollable = Math.max(0, fromContent.scrollHeight - fromEl.clientHeight)
const toScrollable = Math.max(0, toContent.scrollHeight - toEl.clientHeight)
const ratio = fromScrollable > 0 ? fromEl.scrollTop / fromScrollable : 0
toEl.scrollTop = ratio * toScrollable
setTimeout(() => { if (lock === fromEl) lock = null }, 50)
}
this.jogwheelViewport.addEventListener('scroll', () =>
sync(this.jogwheelViewport, this.viewport, this.jogwheelContent, this.content)
)
this.viewport.addEventListener('scroll', () =>
sync(this.viewport, this.jogwheelViewport, this.content, this.jogwheelContent)
)
}
setupSelectionInput() {
if (this.config.select_days === 0) {
this.selectedDateInput.style.display = 'none'