diff options
Diffstat (limited to 'subprojects/frontend/src/editor/scrollbarViewPlugin.ts')
-rw-r--r-- | subprojects/frontend/src/editor/scrollbarViewPlugin.ts | 74 |
1 files changed, 41 insertions, 33 deletions
diff --git a/subprojects/frontend/src/editor/scrollbarViewPlugin.ts b/subprojects/frontend/src/editor/scrollbarViewPlugin.ts index 9ee70441..c1eb2bbd 100644 --- a/subprojects/frontend/src/editor/scrollbarViewPlugin.ts +++ b/subprojects/frontend/src/editor/scrollbarViewPlugin.ts | |||
@@ -22,6 +22,43 @@ export const SCROLLBAR_WIDTH = 12; | |||
22 | export const ANNOTATION_WIDTH = SCROLLBAR_WIDTH / 2; | 22 | export const ANNOTATION_WIDTH = SCROLLBAR_WIDTH / 2; |
23 | export const MIN_ANNOTATION_HEIGHT = 1; | 23 | export const MIN_ANNOTATION_HEIGHT = 1; |
24 | 24 | ||
25 | function handleDrag( | ||
26 | element: HTMLElement, | ||
27 | callback: (movementX: number, movementY: number) => void, | ||
28 | ) { | ||
29 | let pointerId: number | undefined; | ||
30 | element.addEventListener('pointerdown', (event) => { | ||
31 | if (pointerId === undefined) { | ||
32 | ({ pointerId } = event); | ||
33 | element.setPointerCapture(pointerId); | ||
34 | element.classList.add(THUMB_ACTIVE_CLASS); | ||
35 | } else { | ||
36 | event.preventDefault(); | ||
37 | // Avoid implicit pointer capture, see https://w3c.github.io/pointerevents/#dfn-implicit-pointer-capture | ||
38 | element.releasePointerCapture(event.pointerId); | ||
39 | } | ||
40 | }); | ||
41 | |||
42 | element.addEventListener('pointermove', (event) => { | ||
43 | if (event.pointerId !== pointerId) { | ||
44 | return; | ||
45 | } | ||
46 | callback(event.movementX, event.movementY); | ||
47 | event.preventDefault(); | ||
48 | }); | ||
49 | |||
50 | function scrollEnd(event: PointerEvent) { | ||
51 | if (event.pointerId !== pointerId) { | ||
52 | return; | ||
53 | } | ||
54 | pointerId = undefined; | ||
55 | element.classList.remove(THUMB_ACTIVE_CLASS); | ||
56 | } | ||
57 | |||
58 | element.addEventListener('pointerup', scrollEnd, { passive: true }); | ||
59 | element.addEventListener('pointercancel', scrollEnd, { passive: true }); | ||
60 | } | ||
61 | |||
25 | export default function scrollbarViewPlugin( | 62 | export default function scrollbarViewPlugin( |
26 | editorStore: EditorStore, | 63 | editorStore: EditorStore, |
27 | ): ViewPlugin<PluginValue> { | 64 | ): ViewPlugin<PluginValue> { |
@@ -63,44 +100,15 @@ export default function scrollbarViewPlugin( | |||
63 | 100 | ||
64 | const thumbY = ownerDocument.createElement('div'); | 101 | const thumbY = ownerDocument.createElement('div'); |
65 | thumbY.className = `${THUMB_CLASS} ${THUMB_Y_CLASS}`; | 102 | thumbY.className = `${THUMB_CLASS} ${THUMB_Y_CLASS}`; |
66 | const scrollY = (event: MouseEvent) => { | 103 | handleDrag(thumbY, (_movementX, movementY) => |
67 | scrollDOM.scrollBy({ top: event.movementY / factorY }); | 104 | scrollDOM.scrollBy({ top: movementY / factorY }), |
68 | event.preventDefault(); | ||
69 | }; | ||
70 | const stopScrollY = () => { | ||
71 | thumbY.classList.remove(THUMB_ACTIVE_CLASS); | ||
72 | window.removeEventListener('mousemove', scrollY); | ||
73 | window.removeEventListener('mouseup', stopScrollY); | ||
74 | }; | ||
75 | thumbY.addEventListener( | ||
76 | 'mousedown', | ||
77 | () => { | ||
78 | thumbY.classList.add(THUMB_ACTIVE_CLASS); | ||
79 | window.addEventListener('mousemove', scrollY); | ||
80 | window.addEventListener('mouseup', stopScrollY, { passive: true }); | ||
81 | }, | ||
82 | { passive: true }, | ||
83 | ); | 105 | ); |
84 | holder.appendChild(thumbY); | 106 | holder.appendChild(thumbY); |
85 | 107 | ||
86 | const thumbX = ownerDocument.createElement('div'); | 108 | const thumbX = ownerDocument.createElement('div'); |
87 | thumbX.className = `${THUMB_CLASS} ${THUMB_X_CLASS}`; | 109 | thumbX.className = `${THUMB_CLASS} ${THUMB_X_CLASS}`; |
88 | const scrollX = (event: MouseEvent) => { | 110 | handleDrag(thumbX, (movementX) => |
89 | scrollDOM.scrollBy({ left: event.movementX / factorX }); | 111 | scrollDOM.scrollBy({ left: movementX / factorX }), |
90 | }; | ||
91 | const stopScrollX = () => { | ||
92 | thumbX.classList.remove(THUMB_ACTIVE_CLASS); | ||
93 | window.removeEventListener('mousemove', scrollX); | ||
94 | window.removeEventListener('mouseup', stopScrollX); | ||
95 | }; | ||
96 | thumbX.addEventListener( | ||
97 | 'mousedown', | ||
98 | () => { | ||
99 | thumbX.classList.add(THUMB_ACTIVE_CLASS); | ||
100 | window.addEventListener('mousemove', scrollX); | ||
101 | window.addEventListener('mouseup', stopScrollX, { passive: true }); | ||
102 | }, | ||
103 | { passive: true }, | ||
104 | ); | 112 | ); |
105 | holder.appendChild(thumbX); | 113 | holder.appendChild(thumbX); |
106 | 114 | ||