106 lines
3.0 KiB
TypeScript
106 lines
3.0 KiB
TypeScript
import { Spreadsheet } from "../main"
|
|
|
|
export interface ViewportRect {
|
|
top: number
|
|
left: number
|
|
right: number
|
|
bottom: number
|
|
}
|
|
|
|
export class Scroller {
|
|
element: HTMLDivElement
|
|
private verticalScroller: HTMLDivElement
|
|
private horizontalScroller: HTMLDivElement
|
|
private root: Spreadsheet
|
|
|
|
constructor(root: Spreadsheet) {
|
|
this.root = root
|
|
const { horizontalScroller, scroller, verticalScroller } = this.buildComponent()
|
|
this.element = scroller
|
|
this.verticalScroller = verticalScroller
|
|
this.horizontalScroller = horizontalScroller
|
|
|
|
this.element.style.height = this.root.config.view.height + 'px'
|
|
this.element.style.width = this.root.config.view.width + 'px'
|
|
|
|
this.updateScrollerSize() //* Init size set
|
|
|
|
this.element.addEventListener('scroll', this.handleScroll)
|
|
}
|
|
|
|
handleScroll = () => {
|
|
const rect = this.getViewportBoundlingRect()
|
|
this.root.viewport.updateValues(rect)
|
|
|
|
this.root.renderSheet()
|
|
}
|
|
|
|
getViewportBoundlingRect(): ViewportRect {
|
|
const { scrollTop, scrollLeft } = this.element
|
|
const { height, width } = this.element.getBoundingClientRect()
|
|
const bottom = scrollTop + height
|
|
const right = scrollLeft + width
|
|
|
|
return {
|
|
top: scrollTop,
|
|
left: scrollLeft,
|
|
bottom,
|
|
right
|
|
}
|
|
}
|
|
|
|
buildComponent() {
|
|
const scroller = document.createElement('div')
|
|
const verticalScroller = document.createElement('div')
|
|
const horizontalScroller = document.createElement('div')
|
|
const groupScrollers = document.createElement('div')
|
|
const stack = document.createElement('div')
|
|
|
|
verticalScroller.style.width = '0px'
|
|
verticalScroller.style.pointerEvents = 'none'
|
|
|
|
horizontalScroller.style.pointerEvents = 'none'
|
|
|
|
groupScrollers.style.display = 'flex'
|
|
|
|
stack.appendChild(verticalScroller)
|
|
stack.appendChild(horizontalScroller)
|
|
groupScrollers.appendChild(stack)
|
|
this.verticalScroller = verticalScroller
|
|
this.horizontalScroller = horizontalScroller
|
|
scroller.appendChild(groupScrollers)
|
|
scroller.classList.add('scroller')
|
|
|
|
return { scroller, verticalScroller, horizontalScroller }
|
|
}
|
|
|
|
getActualHeight() {
|
|
return this.root.config.rows.reduce((acc, curr) => {
|
|
acc += curr.height
|
|
return acc
|
|
}, 0)
|
|
}
|
|
|
|
getActualWidth() {
|
|
return this.root.config.columns.reduce((acc, curr) => {
|
|
acc += curr.width
|
|
return acc
|
|
}, 0)
|
|
}
|
|
|
|
updateScrollerSize() {
|
|
const totalHeight = this.getActualHeight()
|
|
const totalWidth = this.getActualWidth()
|
|
|
|
this.setScrollerHeight(totalHeight)
|
|
this.setScrollerWidth(totalWidth)
|
|
}
|
|
|
|
setScrollerHeight(height: number) {
|
|
this.verticalScroller.style.height = height + 'px'
|
|
}
|
|
|
|
setScrollerWidth(width: number) {
|
|
this.horizontalScroller.style.width = width + 'px'
|
|
}
|
|
} |