Skip to content

Commit b42f743

Browse files
authored
Merge pull request #954 from x1mrdonut1x/feature/pointer-events
2 parents d93ab1f + ead9904 commit b42f743

File tree

1 file changed

+63
-49
lines changed

1 file changed

+63
-49
lines changed

src/lib/scroll/ScrollElement.tsx

Lines changed: 63 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Component, createRef, CSSProperties, MouseEventHandler, ReactNode} from 'react'
1+
import { Component, createRef, CSSProperties, ReactNode } from 'react'
22
import { getParentPosition } from '../utility/dom-helpers'
33

44
type Props = {
@@ -17,7 +17,7 @@ type State = {
1717
}
1818

1919
class ScrollElement extends Component<Props, State> {
20-
scrollComponentRef = createRef<HTMLDivElement>();
20+
scrollComponentRef = createRef<HTMLDivElement>()
2121
private dragLastPosition: number | null = null
2222
private lastTouchDistance: number | null = null
2323
private singleTouchStart: { x: number; y: number; screenY: number } | null = null
@@ -30,14 +30,40 @@ class ScrollElement extends Component<Props, State> {
3030
}
3131
}
3232
componentDidMount() {
33-
if (this.scrollComponentRef.current) {
34-
this.props.scrollRef(this.scrollComponentRef.current)
35-
this.scrollComponentRef.current.addEventListener('wheel', this.handleWheel, { passive: false })
36-
this.scrollComponentRef.current.addEventListener('itemInteraction', this.handleItemInteract)
37-
this.scrollComponentRef.current.addEventListener('touchstart',this.handleTouchStart,{ passive: false })
38-
this.scrollComponentRef.current.addEventListener("touchmove",this.handleTouchMove,{ passive: false })
39-
}
33+
if (this.scrollComponentRef.current) {
34+
this.props.scrollRef(this.scrollComponentRef.current)
35+
this.scrollComponentRef.current.addEventListener('wheel', this.handleWheel, { passive: false })
36+
this.scrollComponentRef.current.addEventListener('itemInteraction', this.handleItemInteract)
37+
this.scrollComponentRef.current.addEventListener('pointerdown', this.handlePointerStart, { passive: false })
38+
this.scrollComponentRef.current.addEventListener('pointermove', this.handlePointerMove, { passive: false })
39+
this.scrollComponentRef.current.addEventListener('pointerup', this.handlePointerEnd)
40+
this.scrollComponentRef.current.addEventListener('pointerleave', this.handlePointerLeave)
41+
}
42+
}
43+
44+
handlePointerStart = (e: PointerEvent) => {
45+
if (e.pointerType === 'touch') {
46+
this.handleTouchStart(e)
47+
} else if (e.pointerType === 'mouse') {
48+
this.handleMouseDown(e)
49+
}
50+
}
51+
52+
handlePointerMove = (e: PointerEvent) => {
53+
if (e.pointerType === 'touch') {
54+
this.handleTouchMove(e)
55+
} else if (e.pointerType === 'mouse') {
56+
this.handleMouseMove(e)
4057
}
58+
}
59+
60+
handlePointerEnd = (e: PointerEvent) => {
61+
if (e.pointerType === 'touch') {
62+
this.handleTouchEnd()
63+
} else if (e.pointerType === 'mouse') {
64+
this.handleMouseUp()
65+
}
66+
}
4167

4268
/**
4369
* needed to handle scrolling with trackpad
@@ -47,8 +73,6 @@ class ScrollElement extends Component<Props, State> {
4773
this.props.onScroll(scrollX)
4874
}
4975

50-
51-
5276
handleWheel = (e: WheelEvent) => {
5377
//const { traditionalZoom } = this.props
5478

@@ -70,7 +94,7 @@ class ScrollElement extends Component<Props, State> {
7094
}
7195
}
7296

73-
handleMouseDown: MouseEventHandler<HTMLDivElement> = (e) => {
97+
handleMouseDown = (e: PointerEvent) => {
7498
if (e.button === 0) {
7599
this.dragLastPosition = e.pageX
76100
this.setState({
@@ -79,8 +103,7 @@ class ScrollElement extends Component<Props, State> {
79103
}
80104
}
81105

82-
handleMouseMove: MouseEventHandler<HTMLDivElement> = (e) => {
83-
// this.props.onMouseMove(e)
106+
handleMouseMove = (e: PointerEvent) => {
84107
//why is interacting with item important?
85108
if (this.state.isDragging && !this.isItemInteraction) {
86109
this.props.onScroll(this.scrollComponentRef.current!.scrollLeft + this.dragLastPosition! - e.pageX)
@@ -96,52 +119,48 @@ class ScrollElement extends Component<Props, State> {
96119
})
97120
}
98121

99-
handleMouseLeave = () => {
100-
// this.props.onMouseLeave(e)
101-
this.dragLastPosition = null
102-
this.setState({
103-
isDragging: false,
104-
})
122+
handlePointerLeave = (e: PointerEvent) => {
123+
if (e.pointerType === 'mouse') {
124+
this.dragLastPosition = null
125+
this.setState({
126+
isDragging: false,
127+
})
128+
}
105129
}
106130

107-
handleTouchStart = (e:TouchEvent) => {
108-
if (e.touches.length === 2) {
131+
handleTouchStart = (e: PointerEvent) => {
132+
if (e.isPrimary) {
109133
e.preventDefault()
110-
111-
this.lastTouchDistance = Math.abs(e.touches[0].screenX - e.touches[1].screenX)
134+
this.lastTouchDistance = null
135+
this.singleTouchStart = { x: e.clientX, y: e.clientY, screenY: window.scrollY }
136+
this.lastSingleTouch = { x: e.clientX, y: e.clientY, screenY: window.scrollY }
137+
} else {
138+
e.preventDefault()
139+
this.lastTouchDistance = Math.abs(e.clientX - this.singleTouchStart!.x)
112140
this.singleTouchStart = null
113141
this.lastSingleTouch = null
114-
} else if (e.touches.length === 1) {
115-
e.preventDefault()
116-
117-
const x = e.touches[0].clientX
118-
const y = e.touches[0].clientY
119-
120-
this.lastTouchDistance = null
121-
this.singleTouchStart = { x: x, y: y, screenY: window.pageYOffset }
122-
this.lastSingleTouch = { x: x, y: y, screenY: window.pageYOffset }
123142
}
124143
}
125144

126-
handleTouchMove = (e:TouchEvent) => {
145+
handleTouchMove = (e: PointerEvent) => {
127146
const { width, onZoom } = this.props
128147
if (this.isItemInteraction) {
129148
e.preventDefault()
130149
return
131150
}
132-
if (this.lastTouchDistance && e.touches.length === 2) {
151+
if (this.lastTouchDistance && !e.isPrimary) {
133152
e.preventDefault()
134-
const touchDistance = Math.abs(e.touches[0].screenX - e.touches[1].screenX)
153+
const touchDistance = Math.abs(e.clientX - this.singleTouchStart!.x)
135154
const parentPosition = getParentPosition(e.currentTarget as HTMLElement)
136-
const xPosition = (e.touches[0].screenX + e.touches[1].screenX) / 2 - parentPosition.x
155+
const xPosition = (e.clientX + this.singleTouchStart!.x) / 2 - parentPosition.x
137156
if (touchDistance !== 0 && this.lastTouchDistance !== 0) {
138157
onZoom(this.lastTouchDistance / touchDistance, xPosition / width)
139158
this.lastTouchDistance = touchDistance
140159
}
141-
} else if (this.lastSingleTouch && e.touches.length === 1) {
160+
} else if (this.lastSingleTouch && e.isPrimary) {
142161
e.preventDefault()
143-
const x = e.touches[0].clientX
144-
const y = e.touches[0].clientY
162+
const x = e.clientX
163+
const y = e.clientY
145164
const deltaX = x - this.lastSingleTouch.x
146165
const deltaX0 = x - this.singleTouchStart!.x
147166
const deltaY0 = y - this.singleTouchStart!.y
@@ -174,8 +193,10 @@ class ScrollElement extends Component<Props, State> {
174193
if (this.scrollComponentRef.current) {
175194
this.scrollComponentRef.current.removeEventListener('wheel', this.handleWheel)
176195
this.scrollComponentRef.current.removeEventListener('itemInteraction', this.handleItemInteract)
177-
this.scrollComponentRef.current.removeEventListener('touchstart',this.handleTouchStart)
178-
this.scrollComponentRef.current.removeEventListener("touchmove",this.handleTouchMove)
196+
this.scrollComponentRef.current.removeEventListener('pointerdown', this.handlePointerStart)
197+
this.scrollComponentRef.current.removeEventListener('pointermove', this.handlePointerMove)
198+
this.scrollComponentRef.current.removeEventListener('pointerup', this.handlePointerEnd)
199+
this.scrollComponentRef.current.removeEventListener('pointerleave', this.handlePointerLeave)
179200
}
180201
}
181202

@@ -196,13 +217,6 @@ class ScrollElement extends Component<Props, State> {
196217
data-testid="scroll-element"
197218
className="rct-scroll"
198219
style={scrollComponentStyle}
199-
onMouseDown={this.handleMouseDown}
200-
onMouseMove={this.handleMouseMove}
201-
onMouseUp={this.handleMouseUp}
202-
onMouseLeave={this.handleMouseLeave}
203-
// onTouchStart={this.handleTouchStart}
204-
// onTouchMove={this.handleTouchMove}
205-
onTouchEnd={this.handleTouchEnd}
206220
onScroll={this.handleScroll}
207221
>
208222
{children}

0 commit comments

Comments
 (0)