js-draw 0.10.2 → 0.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,12 +25,13 @@ export default class PanZoom extends BaseTool {
25
25
  private lastDist;
26
26
  private lastScreenCenter;
27
27
  private lastTimestamp;
28
+ private lastPointerDownTimestamp;
28
29
  private inertialScroller;
29
30
  private velocity;
30
31
  constructor(editor: Editor, mode: PanZoomMode, description: string);
31
32
  computePinchData(p1: Pointer, p2: Pointer): PinchData;
32
33
  private allPointersAreOfType;
33
- onPointerDown({ allPointers: pointers }: PointerEvt): boolean;
34
+ onPointerDown({ allPointers: pointers, current: currentPointer }: PointerEvt): boolean;
34
35
  private updateVelocity;
35
36
  private getCenterDelta;
36
37
  private handleTwoFingerMove;
@@ -37,19 +37,19 @@ class InertialScroller {
37
37
  if (this.running) {
38
38
  return;
39
39
  }
40
- let currentVelocity = this.initialVelocity;
40
+ this.currentVelocity = this.initialVelocity;
41
41
  let lastTime = (new Date()).getTime();
42
42
  this.running = true;
43
- const maxSpeed = 8000; // units/s
43
+ const maxSpeed = 5000; // units/s
44
44
  const minSpeed = 200; // units/s
45
- if (currentVelocity.magnitude() > maxSpeed) {
46
- currentVelocity = currentVelocity.normalized().times(maxSpeed);
45
+ if (this.currentVelocity.magnitude() > maxSpeed) {
46
+ this.currentVelocity = this.currentVelocity.normalized().times(maxSpeed);
47
47
  }
48
- while (this.running && currentVelocity.magnitude() > minSpeed) {
48
+ while (this.running && this.currentVelocity.magnitude() > minSpeed) {
49
49
  const nowTime = (new Date()).getTime();
50
50
  const dt = (nowTime - lastTime) / 1000;
51
- currentVelocity = currentVelocity.times(Math.pow(1 / 8, dt));
52
- this.scrollBy(currentVelocity.times(dt));
51
+ this.currentVelocity = this.currentVelocity.times(Math.pow(1 / 8, dt));
52
+ this.scrollBy(this.currentVelocity.times(dt));
53
53
  yield untilNextAnimationFrame();
54
54
  lastTime = nowTime;
55
55
  }
@@ -58,6 +58,12 @@ class InertialScroller {
58
58
  }
59
59
  });
60
60
  }
61
+ getCurrentVelocity() {
62
+ if (!this.running) {
63
+ return null;
64
+ }
65
+ return this.currentVelocity;
66
+ }
61
67
  stop() {
62
68
  if (this.running) {
63
69
  this.running = false;
@@ -71,6 +77,7 @@ export default class PanZoom extends BaseTool {
71
77
  this.editor = editor;
72
78
  this.mode = mode;
73
79
  this.transform = null;
80
+ this.lastPointerDownTimestamp = 0;
74
81
  this.inertialScroller = null;
75
82
  this.velocity = null;
76
83
  }
@@ -86,10 +93,13 @@ export default class PanZoom extends BaseTool {
86
93
  allPointersAreOfType(pointers, kind) {
87
94
  return pointers.every(pointer => pointer.device === kind);
88
95
  }
89
- onPointerDown({ allPointers: pointers }) {
90
- var _a, _b;
96
+ onPointerDown({ allPointers: pointers, current: currentPointer }) {
97
+ var _a, _b, _c, _d;
91
98
  let handlingGesture = false;
92
- (_a = this.inertialScroller) === null || _a === void 0 ? void 0 : _a.stop();
99
+ const inertialScrollerVelocity = (_b = (_a = this.inertialScroller) === null || _a === void 0 ? void 0 : _a.getCurrentVelocity()) !== null && _b !== void 0 ? _b : Vec2.zero;
100
+ (_c = this.inertialScroller) === null || _c === void 0 ? void 0 : _c.stop();
101
+ this.velocity = inertialScrollerVelocity;
102
+ this.lastPointerDownTimestamp = currentPointer.timeStamp;
93
103
  const allAreTouch = this.allPointersAreOfType(pointers, PointerDevice.Touch);
94
104
  const isRightClick = this.allPointersAreOfType(pointers, PointerDevice.RightButtonMouse);
95
105
  if (allAreTouch && pointers.length === 2 && this.mode & PanZoomMode.TwoFingerTouchGestures) {
@@ -107,22 +117,24 @@ export default class PanZoom extends BaseTool {
107
117
  }
108
118
  if (handlingGesture) {
109
119
  this.lastTimestamp = (new Date()).getTime();
110
- (_b = this.transform) !== null && _b !== void 0 ? _b : (this.transform = Viewport.transformBy(Mat33.identity));
120
+ (_d = this.transform) !== null && _d !== void 0 ? _d : (this.transform = Viewport.transformBy(Mat33.identity));
111
121
  this.editor.display.setDraftMode(true);
112
122
  }
113
123
  return handlingGesture;
114
124
  }
115
125
  updateVelocity(currentCenter) {
116
126
  const deltaPos = currentCenter.minus(this.lastScreenCenter);
117
- const deltaTime = ((new Date()).getTime() - this.lastTimestamp) / 1000;
118
- // We divide by deltaTime. Don't divide by zero.
119
- if (deltaTime === 0) {
120
- return;
121
- }
127
+ let deltaTime = ((new Date()).getTime() - this.lastTimestamp) / 1000;
122
128
  // Ignore duplicate events, unless there has been enough time between them.
123
129
  if (deltaPos.magnitude() === 0 && deltaTime < 0.1) {
124
130
  return;
125
131
  }
132
+ // We divide by deltaTime. Don't divide by zero.
133
+ if (deltaTime === 0) {
134
+ return;
135
+ }
136
+ // Don't divide by almost zero, either
137
+ deltaTime = Math.max(deltaTime, 0.01);
126
138
  const currentVelocity = deltaPos.times(1 / deltaTime);
127
139
  let smoothedVelocity = currentVelocity;
128
140
  if (this.velocity) {
@@ -184,7 +196,11 @@ export default class PanZoom extends BaseTool {
184
196
  this.transform = null;
185
197
  this.velocity = Vec2.zero;
186
198
  };
187
- const shouldInertialScroll = event.current.device === PointerDevice.Touch && event.allPointers.length === 1;
199
+ const minInertialScrollDt = 30;
200
+ const shouldInertialScroll = event.current.device === PointerDevice.Touch
201
+ && event.allPointers.length === 1
202
+ && this.velocity !== null
203
+ && event.current.timeStamp - this.lastPointerDownTimestamp > minInertialScrollDt;
188
204
  if (shouldInertialScroll && this.velocity !== null) {
189
205
  // If the user drags the screen, then stops, then lifts the pointer,
190
206
  // we want the final velocity to reflect the stop at the end (so the velocity
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-draw",
3
- "version": "0.10.2",
3
+ "version": "0.10.3",
4
4
  "description": "Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript. ",
5
5
  "main": "./dist/src/lib.d.ts",
6
6
  "types": "./dist/src/lib.js",
@@ -83,26 +83,26 @@
83
83
  },
84
84
  "devDependencies": {
85
85
  "@types/bezier-js": "^4.1.0",
86
- "@types/jest": "^29.2.3",
86
+ "@types/jest": "^29.2.5",
87
87
  "@types/jsdom": "^20.0.1",
88
- "@types/node": "^18.11.9",
88
+ "@types/node": "^18.11.18",
89
89
  "@typescript-eslint/eslint-plugin": "^5.44.0",
90
90
  "@typescript-eslint/parser": "^5.44.0",
91
- "css-loader": "^6.7.2",
92
- "eslint": "^8.28.0",
93
- "husky": "^8.0.2",
94
- "jest": "^29.2.3",
91
+ "css-loader": "^6.7.3",
92
+ "eslint": "^8.31.0",
93
+ "husky": "^8.0.3",
94
+ "jest": "^29.3.1",
95
95
  "jest-environment-jsdom": "^29.3.1",
96
96
  "jsdom": "^20.0.3",
97
- "lint-staged": "^13.0.3",
97
+ "lint-staged": "^13.1.0",
98
98
  "pinst": "^3.0.0",
99
99
  "style-loader": "^3.3.1",
100
100
  "terser-webpack-plugin": "^5.3.6",
101
101
  "ts-jest": "^29.0.3",
102
- "ts-loader": "^9.4.1",
102
+ "ts-loader": "^9.4.2",
103
103
  "ts-node": "^10.9.1",
104
- "typedoc": "^0.23.21",
105
- "typescript": "^4.9.3",
104
+ "typedoc": "^0.23.23",
105
+ "typescript": "^4.9.4",
106
106
  "webpack": "^5.75.0"
107
107
  },
108
108
  "bugs": {
@@ -30,6 +30,7 @@ type ScrollByCallback = (delta: Vec2) => void;
30
30
 
31
31
  class InertialScroller {
32
32
  private running: boolean = false;
33
+ private currentVelocity: Vec2;
33
34
 
34
35
  public constructor(
35
36
  private initialVelocity: Vec2,
@@ -44,22 +45,22 @@ class InertialScroller {
44
45
  return;
45
46
  }
46
47
 
47
- let currentVelocity = this.initialVelocity;
48
+ this.currentVelocity = this.initialVelocity;
48
49
  let lastTime = (new Date()).getTime();
49
50
  this.running = true;
50
51
 
51
- const maxSpeed = 8000; // units/s
52
+ const maxSpeed = 5000; // units/s
52
53
  const minSpeed = 200; // units/s
53
- if (currentVelocity.magnitude() > maxSpeed) {
54
- currentVelocity = currentVelocity.normalized().times(maxSpeed);
54
+ if (this.currentVelocity.magnitude() > maxSpeed) {
55
+ this.currentVelocity = this.currentVelocity.normalized().times(maxSpeed);
55
56
  }
56
57
 
57
- while (this.running && currentVelocity.magnitude() > minSpeed) {
58
+ while (this.running && this.currentVelocity.magnitude() > minSpeed) {
58
59
  const nowTime = (new Date()).getTime();
59
60
  const dt = (nowTime - lastTime) / 1000;
60
61
 
61
- currentVelocity = currentVelocity.times(Math.pow(1/8, dt));
62
- this.scrollBy(currentVelocity.times(dt));
62
+ this.currentVelocity = this.currentVelocity.times(Math.pow(1/8, dt));
63
+ this.scrollBy(this.currentVelocity.times(dt));
63
64
 
64
65
  await untilNextAnimationFrame();
65
66
  lastTime = nowTime;
@@ -70,6 +71,14 @@ class InertialScroller {
70
71
  }
71
72
  }
72
73
 
74
+ public getCurrentVelocity(): Vec2|null {
75
+ if (!this.running) {
76
+ return null;
77
+ }
78
+
79
+ return this.currentVelocity;
80
+ }
81
+
73
82
  public stop(): void {
74
83
  if (this.running) {
75
84
  this.running = false;
@@ -85,6 +94,7 @@ export default class PanZoom extends BaseTool {
85
94
  private lastDist: number;
86
95
  private lastScreenCenter: Point2;
87
96
  private lastTimestamp: number;
97
+ private lastPointerDownTimestamp: number = 0;
88
98
 
89
99
  private inertialScroller: InertialScroller|null = null;
90
100
  private velocity: Vec2|null = null;
@@ -108,10 +118,14 @@ export default class PanZoom extends BaseTool {
108
118
  return pointers.every(pointer => pointer.device === kind);
109
119
  }
110
120
 
111
- public onPointerDown({ allPointers: pointers }: PointerEvt): boolean {
121
+ public onPointerDown({ allPointers: pointers, current: currentPointer }: PointerEvt): boolean {
112
122
  let handlingGesture = false;
113
123
 
124
+ const inertialScrollerVelocity = this.inertialScroller?.getCurrentVelocity() ?? Vec2.zero;
114
125
  this.inertialScroller?.stop();
126
+ this.velocity = inertialScrollerVelocity;
127
+
128
+ this.lastPointerDownTimestamp = currentPointer.timeStamp;
115
129
 
116
130
  const allAreTouch = this.allPointersAreOfType(pointers, PointerDevice.Touch);
117
131
  const isRightClick = this.allPointersAreOfType(pointers, PointerDevice.RightButtonMouse);
@@ -142,17 +156,19 @@ export default class PanZoom extends BaseTool {
142
156
 
143
157
  private updateVelocity(currentCenter: Point2) {
144
158
  const deltaPos = currentCenter.minus(this.lastScreenCenter);
145
- const deltaTime = ((new Date()).getTime() - this.lastTimestamp) / 1000;
159
+ let deltaTime = ((new Date()).getTime() - this.lastTimestamp) / 1000;
146
160
 
161
+ // Ignore duplicate events, unless there has been enough time between them.
162
+ if (deltaPos.magnitude() === 0 && deltaTime < 0.1) {
163
+ return;
164
+ }
147
165
  // We divide by deltaTime. Don't divide by zero.
148
166
  if (deltaTime === 0) {
149
167
  return;
150
168
  }
151
169
 
152
- // Ignore duplicate events, unless there has been enough time between them.
153
- if (deltaPos.magnitude() === 0 && deltaTime < 0.1) {
154
- return;
155
- }
170
+ // Don't divide by almost zero, either
171
+ deltaTime = Math.max(deltaTime, 0.01);
156
172
 
157
173
  const currentVelocity = deltaPos.times(1 / deltaTime);
158
174
  let smoothedVelocity = currentVelocity;
@@ -233,8 +249,12 @@ export default class PanZoom extends BaseTool {
233
249
  this.velocity = Vec2.zero;
234
250
  };
235
251
 
252
+ const minInertialScrollDt = 30;
236
253
  const shouldInertialScroll =
237
- event.current.device === PointerDevice.Touch && event.allPointers.length === 1;
254
+ event.current.device === PointerDevice.Touch
255
+ && event.allPointers.length === 1
256
+ && this.velocity !== null
257
+ && event.current.timeStamp - this.lastPointerDownTimestamp > minInertialScrollDt;
238
258
 
239
259
  if (shouldInertialScroll && this.velocity !== null) {
240
260
  // If the user drags the screen, then stops, then lifts the pointer,