UBER-1159: fixed horizontal scrolling in Scroller (#3945)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2023-11-07 07:45:16 +03:00 committed by GitHub
parent cbd7e82e8f
commit b77ad4dc4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -162,60 +162,55 @@
const onScroll = (event: MouseEvent): void => { const onScroll = (event: MouseEvent): void => {
scrolling = false scrolling = false
if (isScrolling && divBar && divScroll) { if (
const rectScroll = divScroll.getBoundingClientRect() (divBar == null && isScrolling === 'vertical') ||
if (isScrolling === 'vertical') { (divBarH == null && isScrolling === 'horizontal') ||
let Y = event.clientY - dXY divScroll == null
if (Y < rectScroll.top + shiftTop + 2) Y = rectScroll.top + shiftTop + 2 ) {
if (Y > rectScroll.bottom - divBar.clientHeight - shiftBottom - 2) { return
Y = rectScroll.bottom - divBar.clientHeight - shiftBottom - 2 }
} const rectScroll = divScroll.getBoundingClientRect()
divBar.style.top = Y - rectScroll.y + 'px' if (isScrolling === 'vertical') {
const topBar = Y - rectScroll.y - shiftTop - 2 let Y = event.clientY - dXY
const heightScroll = rectScroll.height - 4 - divBar.clientHeight - shiftTop - shiftBottom if (Y < rectScroll.top + shiftTop + 2) Y = rectScroll.top + shiftTop + 2
const procBar = topBar / heightScroll if (Y > rectScroll.bottom - divBar.clientHeight - shiftBottom - 2) {
divScroll.scrollTop = (divScroll.scrollHeight - divScroll.clientHeight) * procBar Y = rectScroll.bottom - divBar.clientHeight - shiftBottom - 2
} else {
let X = event.clientX - dXY
if (X < rectScroll.left + 2 + shiftLeft) X = rectScroll.left + 2 + shiftLeft
if (X > rectScroll.right - divBarH.clientWidth - (mask !== 'none' ? 12 : 2) - shiftRight) {
X = rectScroll.right - divBarH.clientWidth - (mask !== 'none' ? 12 : 2) - shiftRight
}
divBarH.style.left = X - rectScroll.x + 'px'
const leftBar = X - rectScroll.x - shiftLeft - 2
const widthScroll =
rectScroll.width - 2 - (mask !== 'none' ? 12 : 2) - divBarH.clientWidth - shiftLeft - shiftRight
const procBar = leftBar / widthScroll
divScroll.scrollLeft = (divScroll.scrollWidth - divScroll.clientWidth) * procBar
} }
divBar.style.top = Y - rectScroll.y + 'px'
const topBar = Y - rectScroll.y - shiftTop - 2
const heightScroll = rectScroll.height - 4 - divBar.clientHeight - shiftTop - shiftBottom
const procBar = topBar / heightScroll
divScroll.scrollTop = (divScroll.scrollHeight - divScroll.clientHeight) * procBar
} else {
let X = event.clientX - dXY
if (X < rectScroll.left + 2 + shiftLeft) X = rectScroll.left + 2 + shiftLeft
if (X > rectScroll.right - divBarH.clientWidth - (mask !== 'none' ? 12 : 2) - shiftRight) {
X = rectScroll.right - divBarH.clientWidth - (mask !== 'none' ? 12 : 2) - shiftRight
}
divBarH.style.left = X - rectScroll.x + 'px'
const leftBar = X - rectScroll.x - shiftLeft - 2
const widthScroll =
rectScroll.width - 2 - (mask !== 'none' ? 12 : 2) - divBarH.clientWidth - shiftLeft - shiftRight
const procBar = leftBar / widthScroll
divScroll.scrollLeft = (divScroll.scrollWidth - divScroll.clientWidth) * procBar
} }
} }
const onScrollEnd = (event: MouseEvent): void => { const onScrollEnd = (): void => {
const el: HTMLElement = event.currentTarget as HTMLElement document.removeEventListener('mousemove', onScroll)
if (el && isScrolling) { document.body.style.userSelect = 'auto'
document.removeEventListener('mousemove', onScroll) document.body.style.webkitUserSelect = 'auto'
// document.body.style.pointerEvents = 'all'
document.body.style.userSelect = 'auto'
document.body.style.webkitUserSelect = 'auto'
}
document.removeEventListener('mouseup', onScrollEnd) document.removeEventListener('mouseup', onScrollEnd)
isScrolling = false isScrolling = false
} }
const onScrollStart = (event: MouseEvent, direction: 'vertical' | 'horizontal'): void => { const onScrollStart = (event: MouseEvent, direction: 'vertical' | 'horizontal'): void => {
if (divScroll == null) return
scrolling = false scrolling = false
const el: HTMLElement = event.currentTarget as HTMLElement dXY = direction === 'vertical' ? event.offsetY : event.offsetX
if (el && divScroll) { document.addEventListener('mouseup', onScrollEnd)
dXY = document.addEventListener('mousemove', onScroll)
direction === 'vertical' document.body.style.userSelect = 'none'
? event.clientY - el.getBoundingClientRect().y document.body.style.webkitUserSelect = 'none'
: event.clientX - el.getBoundingClientRect().x isScrolling = direction
document.addEventListener('mouseup', onScrollEnd)
document.addEventListener('mousemove', onScroll)
// document.body.style.pointerEvents = 'none'
document.body.style.userSelect = 'none'
document.body.style.webkitUserSelect = 'none'
isScrolling = direction
}
} }
const renderFade = () => { const renderFade = () => {
@ -456,37 +451,43 @@
ev: MouseEvent & { currentTarget: EventTarget & HTMLDivElement }, ev: MouseEvent & { currentTarget: EventTarget & HTMLDivElement },
horizontal: boolean = false horizontal: boolean = false
) => { ) => {
if (!isScrolling && divBar && divScroll) { if (
const rectScroll = divScroll.getBoundingClientRect() (divBar == null && !horizontal) ||
if (horizontal) { (divBarH == null && horizontal) ||
const x = ev.offsetX divScroll == null ||
const trackWidth = ev.currentTarget.clientWidth isScrolling !== false
const barWidth = divBarH.clientWidth ) {
const leftBar = return
x - barWidth / 2 <= 0 }
? rectScroll.left + shiftLeft + 2 const rectScroll = divScroll.getBoundingClientRect()
: x + barWidth / 2 >= trackWidth if (horizontal) {
? rectScroll.right - barWidth - shiftRight - (mask !== 'none' ? 12 : 2) const x = ev.offsetX
: ev.clientX - barWidth / 2 const trackWidth = ev.currentTarget.clientWidth
divBarH.style.left = `${leftBar}px` const barWidth = divBarH.clientWidth
const widthScroll = rectScroll.width - 2 - (mask !== 'none' ? 12 : 2) - barWidth - shiftLeft - shiftRight const leftBar =
const procBar = (leftBar - rectScroll.left - shiftLeft - 2) / widthScroll x - barWidth / 2 <= 0
divScroll.scrollLeft = (divScroll.scrollWidth - divScroll.clientWidth) * procBar ? rectScroll.left + shiftLeft + 2
} else { : x + barWidth / 2 >= trackWidth
const y = ev.offsetY ? rectScroll.right - barWidth - shiftRight - (mask !== 'none' ? 12 : 2)
const trackHeight = ev.currentTarget.clientHeight : ev.clientX - barWidth / 2
const barHeight = divBar.clientHeight divBarH.style.left = `${leftBar}px`
const topBar = const widthScroll = rectScroll.width - 2 - (mask !== 'none' ? 12 : 2) - barWidth - shiftLeft - shiftRight
y - barHeight / 2 <= 0 const procBar = (leftBar - rectScroll.left - shiftLeft - 2) / widthScroll
? rectScroll.top + shiftTop + 2 divScroll.scrollLeft = (divScroll.scrollWidth - divScroll.clientWidth) * procBar
: y + barHeight / 2 >= trackHeight } else {
? rectScroll.bottom - barHeight - shiftBottom - 2 const y = ev.offsetY
: ev.clientY - barHeight / 2 const trackHeight = ev.currentTarget.clientHeight
divBar.style.top = `${topBar}px` const barHeight = divBar.clientHeight
const heightScroll = rectScroll.height - 4 - barHeight - shiftTop - shiftBottom const topBar =
const procBar = (topBar - rectScroll.top - shiftTop - 2) / heightScroll y - barHeight / 2 <= 0
divScroll.scrollTop = (divScroll.scrollHeight - divScroll.clientHeight) * procBar ? rectScroll.top + shiftTop + 2
} : y + barHeight / 2 >= trackHeight
? rectScroll.bottom - barHeight - shiftBottom - 2
: ev.clientY - barHeight / 2
divBar.style.top = `${topBar}px`
const heightScroll = rectScroll.height - 4 - barHeight - shiftTop - shiftBottom
const procBar = (topBar - rectScroll.top - shiftTop - 2) / heightScroll
divScroll.scrollTop = (divScroll.scrollHeight - divScroll.clientHeight) * procBar
} }
} }