Skip to content

Commit 2cc809a

Browse files
authored
Merge pull request #20213 from lab-core/pointer-type
[Editor] A new CurrentPointers class to store current pointers used by the editor
2 parents 6e7a6eb + a932804 commit 2cc809a

File tree

2 files changed

+101
-37
lines changed

2 files changed

+101
-37
lines changed

src/display/editor/draw.js

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import { AnnotationEditorParamsType, unreachable } from "../../shared/util.js";
1717
import { noContextMenu, stopEvent } from "../display_utils.js";
1818
import { AnnotationEditor } from "./editor.js";
19+
import { CurrentPointers } from "./tools.js";
1920

2021
class DrawingOptions {
2122
#svgProperties = Object.create(null);
@@ -81,14 +82,6 @@ class DrawingEditor extends AnnotationEditor {
8182

8283
static #currentDrawingOptions = null;
8384

84-
static #currentPointerId = NaN;
85-
86-
static #currentPointerType = null;
87-
88-
static #currentPointerIds = null;
89-
90-
static #currentMoveTimestamp = NaN;
91-
9285
static _INNER_MARGIN = 3;
9386

9487
constructor(params) {
@@ -678,20 +671,15 @@ class DrawingEditor extends AnnotationEditor {
678671
}
679672

680673
static startDrawing(parent, uiManager, _isLTR, event) {
681-
// The _currentPointerType is set when the user starts an empty drawing
682-
// session. If, in the same drawing session, the user starts using a
674+
// The pointerType of CurrentPointer is set when the user starts an empty
675+
// drawing session. If, in the same drawing session, the user starts using a
683676
// different type of pointer (e.g. a pen and then a finger), we just return.
684677
//
685-
// The _currentPointerId and _currentPointerIds are used to keep track of
686-
// the pointers with a same type (e.g. two fingers). If the user starts to
687-
// draw with a finger and then uses a second finger, we just stop the
688-
// current drawing and let the user zoom the document.
678+
// If the user starts to draw with a finger and then uses a second finger,
679+
// we just stop the current drawing and let the user zoom the document.
689680

690681
const { target, offsetX: x, offsetY: y, pointerId, pointerType } = event;
691-
if (
692-
DrawingEditor.#currentPointerType &&
693-
DrawingEditor.#currentPointerType !== pointerType
694-
) {
682+
if (CurrentPointers.isInitializedAndDifferentPointerType(pointerType)) {
695683
return;
696684
}
697685

@@ -704,42 +692,37 @@ class DrawingEditor extends AnnotationEditor {
704692
const ac = (DrawingEditor.#currentDrawingAC = new AbortController());
705693
const signal = parent.combinedSignal(ac);
706694

707-
DrawingEditor.#currentPointerId ||= pointerId;
708-
DrawingEditor.#currentPointerType ??= pointerType;
695+
CurrentPointers.setPointer(pointerType, pointerId);
709696

710697
window.addEventListener(
711698
"pointerup",
712699
e => {
713-
if (DrawingEditor.#currentPointerId === e.pointerId) {
700+
if (CurrentPointers.isSamePointerIdOrRemove(e.pointerId)) {
714701
this._endDraw(e);
715-
} else {
716-
DrawingEditor.#currentPointerIds?.delete(e.pointerId);
717702
}
718703
},
719704
{ signal }
720705
);
721706
window.addEventListener(
722707
"pointercancel",
723708
e => {
724-
if (DrawingEditor.#currentPointerId === e.pointerId) {
709+
if (CurrentPointers.isSamePointerIdOrRemove(e.pointerId)) {
725710
this._currentParent.endDrawingSession();
726-
} else {
727-
DrawingEditor.#currentPointerIds?.delete(e.pointerId);
728711
}
729712
},
730713
{ signal }
731714
);
732715
window.addEventListener(
733716
"pointerdown",
734717
e => {
735-
if (DrawingEditor.#currentPointerType !== e.pointerType) {
718+
if (!CurrentPointers.isSamePointerType(e.pointerType)) {
736719
// For example, we started with a pen and the user
737720
// is now using a finger.
738721
return;
739722
}
740723

741724
// For example, the user is using a second finger.
742-
(DrawingEditor.#currentPointerIds ||= new Set()).add(e.pointerId);
725+
CurrentPointers.initializeAndAddPointerId(e.pointerId);
743726

744727
// The first finger created a first point and a second finger just
745728
// started, so we stop the drawing and remove this only point.
@@ -765,7 +748,7 @@ class DrawingEditor extends AnnotationEditor {
765748
target.addEventListener(
766749
"touchmove",
767750
e => {
768-
if (e.timeStamp === DrawingEditor.#currentMoveTimestamp) {
751+
if (CurrentPointers.isSameTimeStamp(e.timeStamp)) {
769752
// This move event is used to draw so we don't want to scroll.
770753
stopEvent(e);
771754
}
@@ -812,16 +795,16 @@ class DrawingEditor extends AnnotationEditor {
812795
}
813796

814797
static _drawMove(event) {
815-
DrawingEditor.#currentMoveTimestamp = -1;
798+
CurrentPointers.isSameTimeStamp(event.timeStamp);
816799
if (!DrawingEditor.#currentDraw) {
817800
return;
818801
}
819802
const { offsetX, offsetY, pointerId } = event;
820803

821-
if (DrawingEditor.#currentPointerId !== pointerId) {
804+
if (!CurrentPointers.isSamePointerId(pointerId)) {
822805
return;
823806
}
824-
if (DrawingEditor.#currentPointerIds?.size >= 1) {
807+
if (CurrentPointers.isUsingMultiplePointers()) {
825808
// The user is using multiple fingers and the first one is moving.
826809
this._endDraw(event);
827810
return;
@@ -831,7 +814,7 @@ class DrawingEditor extends AnnotationEditor {
831814
DrawingEditor.#currentDraw.add(offsetX, offsetY)
832815
);
833816
// We track the timestamp to know if the touchmove event is used to draw.
834-
DrawingEditor.#currentMoveTimestamp = event.timeStamp;
817+
CurrentPointers.setTimeStamp(event.timeStamp);
835818
stopEvent(event);
836819
}
837820

@@ -841,15 +824,14 @@ class DrawingEditor extends AnnotationEditor {
841824
this._currentParent = null;
842825
DrawingEditor.#currentDraw = null;
843826
DrawingEditor.#currentDrawingOptions = null;
844-
DrawingEditor.#currentPointerType = null;
845-
DrawingEditor.#currentMoveTimestamp = NaN;
827+
CurrentPointers.clearPointerType();
828+
CurrentPointers.clearTimeStamp();
846829
}
847830

848831
if (DrawingEditor.#currentDrawingAC) {
849832
DrawingEditor.#currentDrawingAC.abort();
850833
DrawingEditor.#currentDrawingAC = null;
851-
DrawingEditor.#currentPointerId = NaN;
852-
DrawingEditor.#currentPointerIds = null;
834+
CurrentPointers.clearPointerIds();
853835
}
854836
}
855837

src/display/editor/tools.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,87 @@ function bindEvents(obj, element, names) {
4242
}
4343
}
4444

45+
/**
46+
* Class to store current pointers used by the editor to be able to handle
47+
* multiple pointers (e.g. two fingers, a pen, a mouse, ...).
48+
*/
49+
class CurrentPointers {
50+
// To manage the pointer events.
51+
52+
// The pointerId and pointerIds are used to keep track of
53+
// the pointers with a same type (e.g. two fingers).
54+
static #pointerId = NaN;
55+
56+
static #pointerIds = null;
57+
58+
// Track the timestamp to know if the touchmove event is used.
59+
static #moveTimestamp = NaN;
60+
61+
// The pointerType is used to know if we are using a mouse, a pen or a touch.
62+
static #pointerType = null;
63+
64+
static initializeAndAddPointerId(pointerId) {
65+
// Store pointer ids. For example, the user is using a second finger.
66+
(CurrentPointers.#pointerIds ||= new Set()).add(pointerId);
67+
}
68+
69+
static setPointer(pointerType, pointerId) {
70+
CurrentPointers.#pointerId ||= pointerId;
71+
CurrentPointers.#pointerType ??= pointerType;
72+
}
73+
74+
static setTimeStamp(timeStamp) {
75+
CurrentPointers.#moveTimestamp = timeStamp;
76+
}
77+
78+
static isSamePointerId(pointerId) {
79+
return CurrentPointers.#pointerId === pointerId;
80+
}
81+
82+
// Check if it's the same pointer id, otherwise remove it from the set.
83+
static isSamePointerIdOrRemove(pointerId) {
84+
if (CurrentPointers.#pointerId === pointerId) {
85+
return true;
86+
}
87+
88+
CurrentPointers.#pointerIds?.delete(pointerId);
89+
return false;
90+
}
91+
92+
static isSamePointerType(pointerType) {
93+
return CurrentPointers.#pointerType === pointerType;
94+
}
95+
96+
static isInitializedAndDifferentPointerType(pointerType) {
97+
return (
98+
CurrentPointers.#pointerType !== null &&
99+
!CurrentPointers.isSamePointerType(pointerType)
100+
);
101+
}
102+
103+
static isSameTimeStamp(timeStamp) {
104+
return CurrentPointers.#moveTimestamp === timeStamp;
105+
}
106+
107+
static isUsingMultiplePointers() {
108+
// Check if the user is using multiple fingers
109+
return CurrentPointers.#pointerIds?.size >= 1;
110+
}
111+
112+
static clearPointerType() {
113+
CurrentPointers.#pointerType = null;
114+
}
115+
116+
static clearPointerIds() {
117+
CurrentPointers.#pointerId = NaN;
118+
CurrentPointers.#pointerIds = null;
119+
}
120+
121+
static clearTimeStamp() {
122+
CurrentPointers.#moveTimestamp = NaN;
123+
}
124+
}
125+
45126
/**
46127
* Class to create some unique ids for the different editors.
47128
*/
@@ -2801,5 +2882,6 @@ export {
28012882
bindEvents,
28022883
ColorManager,
28032884
CommandManager,
2885+
CurrentPointers,
28042886
KeyboardManager,
28052887
};

0 commit comments

Comments
 (0)