@m2c2kit/addons 0.3.12 → 0.3.14
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.
- package/dist/index.d.ts +139 -58
- package/dist/index.js +411 -172
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +1 -0
- package/package.json +10 -8
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Composite, WebColors, Shape, Label, CanvasKitHelpers,
|
|
1
|
+
import { Composite, WebColors, Shape, Label, CanvasKitHelpers, M2EventType, MutablePath, Easings, Story, Transition, TransitionDirection, LabelHorizontalAlignmentMode, Scene, Dimensions, Sprite, Action } from '@m2c2kit/core';
|
|
2
2
|
|
|
3
3
|
class Grid extends Composite {
|
|
4
4
|
/**
|
|
5
|
-
* A rectangular grid that supports placement of
|
|
5
|
+
* A rectangular grid that supports placement of nodes within the grid's
|
|
6
6
|
* cells.
|
|
7
7
|
*
|
|
8
|
-
* @remarks This composite
|
|
9
|
-
* has convenience functions for placing and clearing
|
|
8
|
+
* @remarks This composite node is composed of rectangles and lines. It
|
|
9
|
+
* has convenience functions for placing and clearing nodes on the grid
|
|
10
10
|
* by row and column position (zero-based indexing)
|
|
11
11
|
*
|
|
12
12
|
* @param options - {@link GridOptions}
|
|
@@ -102,11 +102,11 @@ class Grid extends Composite {
|
|
|
102
102
|
}
|
|
103
103
|
const x = -this.size.width / 2 + this.cellWidth / 2 + gridChild.column * this.cellWidth;
|
|
104
104
|
const y = -this.size.height / 2 + this.cellHeight / 2 + gridChild.row * this.cellHeight;
|
|
105
|
-
gridChild.
|
|
106
|
-
x: x + gridChild.
|
|
107
|
-
y: y + gridChild.
|
|
105
|
+
gridChild.node.position = {
|
|
106
|
+
x: x + gridChild.node.position.x,
|
|
107
|
+
y: y + gridChild.node.position.y
|
|
108
108
|
};
|
|
109
|
-
this.gridBackground.addChild(gridChild.
|
|
109
|
+
this.gridBackground.addChild(gridChild.node);
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
112
|
this.needsInitialization = false;
|
|
@@ -120,24 +120,24 @@ class Grid extends Composite {
|
|
|
120
120
|
set gridBackground(gridBackground) {
|
|
121
121
|
this._gridBackground = gridBackground;
|
|
122
122
|
}
|
|
123
|
-
// all
|
|
123
|
+
// all nodes that make up grid are added as children, so they
|
|
124
124
|
// have their own dispose methods
|
|
125
125
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
126
126
|
dispose() {
|
|
127
127
|
}
|
|
128
128
|
/**
|
|
129
|
-
* Duplicates
|
|
129
|
+
* Duplicates a node using deep copy.
|
|
130
130
|
*
|
|
131
|
-
* @remarks This is a deep recursive clone (
|
|
132
|
-
* The uuid property of all duplicated
|
|
131
|
+
* @remarks This is a deep recursive clone (node and children).
|
|
132
|
+
* The uuid property of all duplicated nodes will be newly created,
|
|
133
133
|
* because uuid must be unique.
|
|
134
134
|
*
|
|
135
|
-
* @param newName - optional name of the new, duplicated
|
|
135
|
+
* @param newName - optional name of the new, duplicated node. If not
|
|
136
136
|
* provided, name will be the new uuid
|
|
137
137
|
*/
|
|
138
138
|
duplicate(newName) {
|
|
139
139
|
const dest = new Grid({
|
|
140
|
-
...this.
|
|
140
|
+
...this.getNodeOptions(),
|
|
141
141
|
...this.getDrawableOptions(),
|
|
142
142
|
rows: this.rows,
|
|
143
143
|
columns: this.columns,
|
|
@@ -168,8 +168,8 @@ class Grid extends Composite {
|
|
|
168
168
|
child.warmup(canvas);
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
|
-
// override
|
|
172
|
-
// it removes only
|
|
171
|
+
// override M2Node.RemoveAllChildren() so that when RemoveAllChildren() is called on a Grid,
|
|
172
|
+
// it removes only nodes added to the grid cells (what we call grid children), not the grid lines!
|
|
173
173
|
/**
|
|
174
174
|
* Removes all children from the grid, but retains grid lines.
|
|
175
175
|
*/
|
|
@@ -180,29 +180,29 @@ class Grid extends Composite {
|
|
|
180
180
|
while (this.gridChildren.length) {
|
|
181
181
|
const gridChild = this.gridChildren.pop();
|
|
182
182
|
if (gridChild) {
|
|
183
|
-
this.gridBackground.removeChild(gridChild.
|
|
183
|
+
this.gridBackground.removeChild(gridChild.node);
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
this.needsInitialization = true;
|
|
187
187
|
}
|
|
188
188
|
/**
|
|
189
|
-
* Adds
|
|
189
|
+
* Adds a node to the grid at the specified row and column position.
|
|
190
190
|
*
|
|
191
|
-
* @param
|
|
192
|
-
* @param row - row position within grid to add
|
|
193
|
-
* @param column - column position within grid to add
|
|
191
|
+
* @param node - node to add to the grid
|
|
192
|
+
* @param row - row position within grid to add node; zero-based indexing
|
|
193
|
+
* @param column - column position within grid to add node; zero-based indexing
|
|
194
194
|
*/
|
|
195
|
-
addAtCell(
|
|
195
|
+
addAtCell(node, row, column) {
|
|
196
196
|
if (row < 0 || row >= this.rows || column < 0 || column >= this.columns) {
|
|
197
197
|
console.warn(
|
|
198
|
-
`warning: addAtCell() requested to add
|
|
198
|
+
`warning: addAtCell() requested to add node at row ${row}, column ${column}. This is outside the bounds of grid ${this.name}, which is size ${this.rows}x${this.columns}. Note that addAtCell() uses zero-based indexing. AddAtCell() will proceed, but may draw nodes outside the grid`
|
|
199
199
|
);
|
|
200
200
|
}
|
|
201
|
-
this.gridChildren.push({
|
|
201
|
+
this.gridChildren.push({ node, row, column });
|
|
202
202
|
this.needsInitialization = true;
|
|
203
203
|
}
|
|
204
204
|
/**
|
|
205
|
-
* Removes all child
|
|
205
|
+
* Removes all child nodes at the specified row and column position.
|
|
206
206
|
*
|
|
207
207
|
* @param row - row position within grid at which to remove children; zero-based indexing
|
|
208
208
|
* @param column - column position within grid at which to remove children; zero-based indexing
|
|
@@ -215,24 +215,24 @@ class Grid extends Composite {
|
|
|
215
215
|
return;
|
|
216
216
|
}
|
|
217
217
|
this.gridBackground.removeChildren(
|
|
218
|
-
gridChildrenToRemove.map((gridChild) => gridChild.
|
|
218
|
+
gridChildrenToRemove.map((gridChild) => gridChild.node)
|
|
219
219
|
);
|
|
220
220
|
this.gridChildren = this.gridChildren.filter(
|
|
221
221
|
(gridChild) => gridChild.row !== row && gridChild.column !== column
|
|
222
222
|
);
|
|
223
223
|
this.needsInitialization = true;
|
|
224
224
|
}
|
|
225
|
-
// override
|
|
226
|
-
//
|
|
225
|
+
// override M2Node.RemoveChild() so that when RemoveChild() is called on a Grid, it removes the
|
|
226
|
+
// node from the gridBackground rectangle AND our grid's own list of children (in gridChildren)
|
|
227
227
|
/**
|
|
228
|
-
* Removes the child
|
|
228
|
+
* Removes the child node from the grid.
|
|
229
229
|
*
|
|
230
|
-
* @param
|
|
230
|
+
* @param node - node to remove
|
|
231
231
|
*/
|
|
232
|
-
removeChild(
|
|
233
|
-
this.gridBackground.removeChild(
|
|
232
|
+
removeChild(node) {
|
|
233
|
+
this.gridBackground.removeChild(node);
|
|
234
234
|
this.gridChildren = this.gridChildren.filter(
|
|
235
|
-
(gridChild) => gridChild.
|
|
235
|
+
(gridChild) => gridChild.node != node
|
|
236
236
|
);
|
|
237
237
|
this.needsInitialization = true;
|
|
238
238
|
}
|
|
@@ -244,7 +244,7 @@ class Button extends Composite {
|
|
|
244
244
|
/**
|
|
245
245
|
* A simple button of rectangle with text centered inside.
|
|
246
246
|
*
|
|
247
|
-
* @remarks This composite
|
|
247
|
+
* @remarks This composite node is composed of a rectangle and text. To
|
|
248
248
|
* respond to user taps, the isUserInteractionEnabled property must be set
|
|
249
249
|
* to true and an appropriate callback must be set to handle the tap event.
|
|
250
250
|
*
|
|
@@ -258,7 +258,7 @@ class Button extends Composite {
|
|
|
258
258
|
this.size = { width: 200, height: 50 };
|
|
259
259
|
this.cornerRadius = 9;
|
|
260
260
|
this.fontSize = 20;
|
|
261
|
-
this.
|
|
261
|
+
this._text = "";
|
|
262
262
|
this._fontColor = WebColors.White;
|
|
263
263
|
if (options.text) {
|
|
264
264
|
this.text = options.text;
|
|
@@ -266,10 +266,10 @@ class Button extends Composite {
|
|
|
266
266
|
if (options.size) {
|
|
267
267
|
this.size = options.size;
|
|
268
268
|
}
|
|
269
|
-
if (options.cornerRadius) {
|
|
269
|
+
if (options.cornerRadius !== void 0) {
|
|
270
270
|
this.cornerRadius = options.cornerRadius;
|
|
271
271
|
}
|
|
272
|
-
if (options.fontSize) {
|
|
272
|
+
if (options.fontSize !== void 0) {
|
|
273
273
|
this.fontSize = options.fontSize;
|
|
274
274
|
}
|
|
275
275
|
if (options.fontColor) {
|
|
@@ -308,6 +308,13 @@ class Button extends Composite {
|
|
|
308
308
|
dispose() {
|
|
309
309
|
CanvasKitHelpers.Dispose([this.backgroundPaint]);
|
|
310
310
|
}
|
|
311
|
+
get text() {
|
|
312
|
+
return this._text;
|
|
313
|
+
}
|
|
314
|
+
set text(text) {
|
|
315
|
+
this._text = text;
|
|
316
|
+
this.needsInitialization = true;
|
|
317
|
+
}
|
|
311
318
|
get backgroundColor() {
|
|
312
319
|
return this._backgroundColor;
|
|
313
320
|
}
|
|
@@ -323,18 +330,18 @@ class Button extends Composite {
|
|
|
323
330
|
this.needsInitialization = true;
|
|
324
331
|
}
|
|
325
332
|
/**
|
|
326
|
-
* Duplicates
|
|
333
|
+
* Duplicates a node using deep copy.
|
|
327
334
|
*
|
|
328
|
-
* @remarks This is a deep recursive clone (
|
|
329
|
-
* The uuid property of all duplicated
|
|
335
|
+
* @remarks This is a deep recursive clone (node and children).
|
|
336
|
+
* The uuid property of all duplicated nodes will be newly created,
|
|
330
337
|
* because uuid must be unique.
|
|
331
338
|
*
|
|
332
|
-
* @param newName - optional name of the new, duplicated
|
|
339
|
+
* @param newName - optional name of the new, duplicated node. If not
|
|
333
340
|
* provided, name will be the new uuid
|
|
334
341
|
*/
|
|
335
342
|
duplicate(newName) {
|
|
336
343
|
const dest = new Button({
|
|
337
|
-
...this.
|
|
344
|
+
...this.getNodeOptions(),
|
|
338
345
|
...this.getDrawableOptions(),
|
|
339
346
|
...this.getTextOptions(),
|
|
340
347
|
size: this.size,
|
|
@@ -377,7 +384,7 @@ class Dialog extends Composite {
|
|
|
377
384
|
// todo: add default "behaviors" (?) like button click animation?
|
|
378
385
|
constructor(options) {
|
|
379
386
|
super(options);
|
|
380
|
-
this.compositeType = "
|
|
387
|
+
this.compositeType = "Dialog";
|
|
381
388
|
this._backgroundColor = WebColors.White;
|
|
382
389
|
this.cornerRadius = 9;
|
|
383
390
|
this.overlayAlpha = 0.5;
|
|
@@ -418,15 +425,16 @@ class Dialog extends Composite {
|
|
|
418
425
|
show() {
|
|
419
426
|
this.hidden = false;
|
|
420
427
|
}
|
|
421
|
-
onDialogResult(callback,
|
|
428
|
+
onDialogResult(callback, options) {
|
|
422
429
|
const eventListener = {
|
|
423
|
-
type:
|
|
424
|
-
|
|
430
|
+
type: M2EventType.CompositeCustom,
|
|
431
|
+
compositeType: "DialogResult",
|
|
432
|
+
nodeUuid: this.uuid,
|
|
425
433
|
callback
|
|
426
434
|
};
|
|
427
|
-
if (
|
|
435
|
+
if (options?.replaceExisting) {
|
|
428
436
|
this.eventListeners = this.eventListeners.filter(
|
|
429
|
-
(listener) => !(listener.
|
|
437
|
+
(listener) => !(listener.nodeUuid === eventListener.nodeUuid && listener.type === eventListener.type)
|
|
430
438
|
);
|
|
431
439
|
}
|
|
432
440
|
this.eventListeners.push(eventListener);
|
|
@@ -448,9 +456,9 @@ class Dialog extends Composite {
|
|
|
448
456
|
e.handled = true;
|
|
449
457
|
this.hidden = true;
|
|
450
458
|
if (this.eventListeners.length > 0) {
|
|
451
|
-
this.eventListeners.filter((listener) => listener.type ===
|
|
459
|
+
this.eventListeners.filter((listener) => listener.type === M2EventType.CompositeCustom).forEach((listener) => {
|
|
452
460
|
const dialogEvent = {
|
|
453
|
-
type:
|
|
461
|
+
type: M2EventType.CompositeCustom,
|
|
454
462
|
target: this,
|
|
455
463
|
handled: false,
|
|
456
464
|
dialogResult: "Dismiss" /* Dismiss */
|
|
@@ -496,9 +504,9 @@ class Dialog extends Composite {
|
|
|
496
504
|
e.handled = true;
|
|
497
505
|
this.hidden = true;
|
|
498
506
|
if (this.eventListeners.length > 0) {
|
|
499
|
-
this.eventListeners.filter((listener) => listener.type ===
|
|
507
|
+
this.eventListeners.filter((listener) => listener.type === M2EventType.CompositeCustom).forEach((listener) => {
|
|
500
508
|
const dialogEvent = {
|
|
501
|
-
type:
|
|
509
|
+
type: M2EventType.CompositeCustom,
|
|
502
510
|
target: this,
|
|
503
511
|
handled: false,
|
|
504
512
|
dialogResult: "Negative" /* Negative */
|
|
@@ -518,9 +526,9 @@ class Dialog extends Composite {
|
|
|
518
526
|
e.handled = true;
|
|
519
527
|
this.hidden = true;
|
|
520
528
|
if (this.eventListeners.length > 0) {
|
|
521
|
-
this.eventListeners.filter((listener) => listener.type ===
|
|
529
|
+
this.eventListeners.filter((listener) => listener.type === M2EventType.CompositeCustom).forEach((listener) => {
|
|
522
530
|
const dialogEvent = {
|
|
523
|
-
type:
|
|
531
|
+
type: M2EventType.CompositeCustom,
|
|
524
532
|
target: this,
|
|
525
533
|
handled: false,
|
|
526
534
|
dialogResult: "Positive" /* Positive */
|
|
@@ -548,13 +556,13 @@ class Dialog extends Composite {
|
|
|
548
556
|
this.needsInitialization = true;
|
|
549
557
|
}
|
|
550
558
|
/**
|
|
551
|
-
* Duplicates
|
|
559
|
+
* Duplicates a node using deep copy.
|
|
552
560
|
*
|
|
553
|
-
* @remarks This is a deep recursive clone (
|
|
554
|
-
* The uuid property of all duplicated
|
|
561
|
+
* @remarks This is a deep recursive clone (node and children).
|
|
562
|
+
* The uuid property of all duplicated nodes will be newly created,
|
|
555
563
|
* because uuid must be unique.
|
|
556
564
|
*
|
|
557
|
-
* @param newName - optional name of the new, duplicated
|
|
565
|
+
* @param newName - optional name of the new, duplicated node. If not
|
|
558
566
|
* provided, name will be the new uuid
|
|
559
567
|
*/
|
|
560
568
|
duplicate(newName) {
|
|
@@ -587,7 +595,7 @@ class DrawPad extends Composite {
|
|
|
587
595
|
/**
|
|
588
596
|
* A rectangular area on which the user can draw strokes (lines).
|
|
589
597
|
*
|
|
590
|
-
* @remarks This composite
|
|
598
|
+
* @remarks This composite node is composed of a rectangle Shape and
|
|
591
599
|
* another Shape that is formed from a path of points.
|
|
592
600
|
*
|
|
593
601
|
* @param options - {@link DrawPadOptions}
|
|
@@ -674,8 +682,8 @@ class DrawPad extends Composite {
|
|
|
674
682
|
this.drawArea.onTapUpAny(() => {
|
|
675
683
|
this.handleTapUpAny();
|
|
676
684
|
});
|
|
677
|
-
this.drawArea.onTapLeave(() => {
|
|
678
|
-
this.handleTapLeave();
|
|
685
|
+
this.drawArea.onTapLeave((e) => {
|
|
686
|
+
this.handleTapLeave(e);
|
|
679
687
|
});
|
|
680
688
|
}
|
|
681
689
|
this.drawArea.fillColor = this.backgroundColor;
|
|
@@ -687,11 +695,10 @@ class DrawPad extends Composite {
|
|
|
687
695
|
}
|
|
688
696
|
handleTapDown(e) {
|
|
689
697
|
if (this.isUserInteractionEnabled) {
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
throw new Error("no draw shape");
|
|
698
|
+
if (!this.drawShape?.path) {
|
|
699
|
+
throw new Error("DrawPad.handleTapDown(): no drawShape.path");
|
|
693
700
|
}
|
|
694
|
-
const path = drawShape.path;
|
|
701
|
+
const path = this.drawShape.path;
|
|
695
702
|
if (this.continuousDrawingOnly && path.subpaths.length !== 0) {
|
|
696
703
|
const prevPoint = path.subpaths[path.subpaths.length - 1][path.subpaths[path.subpaths.length - 1].length - 1];
|
|
697
704
|
const currentPoint = e.point;
|
|
@@ -700,6 +707,7 @@ class DrawPad extends Composite {
|
|
|
700
707
|
return;
|
|
701
708
|
}
|
|
702
709
|
}
|
|
710
|
+
this.currentStrokesNotAllowed = false;
|
|
703
711
|
this.isDrawingPointerDown = true;
|
|
704
712
|
path.move(e.point);
|
|
705
713
|
const drawPadEvent = {
|
|
@@ -712,13 +720,43 @@ class DrawPad extends Composite {
|
|
|
712
720
|
{
|
|
713
721
|
type: DrawPadEventType.StrokeStart,
|
|
714
722
|
position: e.point,
|
|
715
|
-
iso8601Timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
723
|
+
iso8601Timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
724
|
+
interpolated: false
|
|
716
725
|
}
|
|
717
726
|
]);
|
|
718
727
|
this.raiseDrawPadEvent(drawPadEvent);
|
|
719
728
|
}
|
|
720
729
|
}
|
|
721
|
-
|
|
730
|
+
addInterpolatedStrokeMove(point) {
|
|
731
|
+
const strokeCount = this.strokes.length;
|
|
732
|
+
const strokeInteractionCount = this.strokes[strokeCount - 1].length;
|
|
733
|
+
const previousPoint = this.strokes[this.strokes.length - 1][strokeInteractionCount - 1].position;
|
|
734
|
+
const interpolatedPoint = this.interpolateToDrawPadBorder(
|
|
735
|
+
point,
|
|
736
|
+
previousPoint,
|
|
737
|
+
this.size
|
|
738
|
+
);
|
|
739
|
+
if (!this.drawShape?.path) {
|
|
740
|
+
throw new Error("DrawPad.addInterpolatedStrokeMove(): no drawShape.path");
|
|
741
|
+
}
|
|
742
|
+
const path = this.drawShape.path;
|
|
743
|
+
path.addLine(interpolatedPoint);
|
|
744
|
+
const drawPadEvent = {
|
|
745
|
+
type: DrawPadEventType.StrokeMove,
|
|
746
|
+
target: this,
|
|
747
|
+
handled: false,
|
|
748
|
+
position: interpolatedPoint
|
|
749
|
+
};
|
|
750
|
+
this.strokes[strokeCount - 1].push({
|
|
751
|
+
type: DrawPadEventType.StrokeMove,
|
|
752
|
+
position: interpolatedPoint,
|
|
753
|
+
iso8601Timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
754
|
+
interpolated: true
|
|
755
|
+
});
|
|
756
|
+
this.raiseDrawPadEvent(drawPadEvent);
|
|
757
|
+
return interpolatedPoint;
|
|
758
|
+
}
|
|
759
|
+
handleTapLeave(e) {
|
|
722
760
|
if (this.currentStrokesNotAllowed) {
|
|
723
761
|
this.isDrawingPointerDown = false;
|
|
724
762
|
return;
|
|
@@ -727,6 +765,12 @@ class DrawPad extends Composite {
|
|
|
727
765
|
this.isDrawingPointerDown = false;
|
|
728
766
|
const strokeCount = this.strokes.length;
|
|
729
767
|
const strokeInteractionCount = this.strokes[strokeCount - 1].length;
|
|
768
|
+
let pointWasInterpolated = false;
|
|
769
|
+
let point = e.point;
|
|
770
|
+
if (!this.isPointWithinDrawPad(e.point, this.size)) {
|
|
771
|
+
point = this.addInterpolatedStrokeMove(e.point);
|
|
772
|
+
pointWasInterpolated = true;
|
|
773
|
+
}
|
|
730
774
|
const drawPadEvent = {
|
|
731
775
|
type: DrawPadEventType.StrokeEnd,
|
|
732
776
|
position: this.strokes[strokeCount - 1][strokeInteractionCount - 1].position,
|
|
@@ -735,10 +779,12 @@ class DrawPad extends Composite {
|
|
|
735
779
|
};
|
|
736
780
|
this.strokes[strokeCount - 1].push({
|
|
737
781
|
type: DrawPadEventType.StrokeEnd,
|
|
738
|
-
position: this.strokes[strokeCount - 1][strokeInteractionCount - 1].position,
|
|
739
|
-
iso8601Timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
782
|
+
position: pointWasInterpolated ? point : this.strokes[strokeCount - 1][strokeInteractionCount - 1].position,
|
|
783
|
+
iso8601Timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
784
|
+
interpolated: pointWasInterpolated
|
|
740
785
|
});
|
|
741
786
|
this.raiseDrawPadEvent(drawPadEvent);
|
|
787
|
+
this.currentStrokesNotAllowed = true;
|
|
742
788
|
} else {
|
|
743
789
|
this.pointerIsDownAndPointerLeftDrawAreaWhenDown = true;
|
|
744
790
|
}
|
|
@@ -762,18 +808,18 @@ class DrawPad extends Composite {
|
|
|
762
808
|
this.strokes[strokeCount - 1].push({
|
|
763
809
|
type: DrawPadEventType.StrokeEnd,
|
|
764
810
|
position: this.strokes[strokeCount - 1][strokeInteractionCount - 1].position,
|
|
765
|
-
iso8601Timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
811
|
+
iso8601Timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
812
|
+
interpolated: false
|
|
766
813
|
});
|
|
767
814
|
this.raiseDrawPadEvent(drawPadEvent);
|
|
768
815
|
}
|
|
769
816
|
}
|
|
770
817
|
handlePointerMove(e) {
|
|
771
818
|
if (this.isUserInteractionEnabled && this.isDrawingPointerDown) {
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
throw new Error("no draw shape");
|
|
819
|
+
if (!this.drawShape?.path) {
|
|
820
|
+
throw new Error("DrawPad.handlePointerMove(): no drawShape.path");
|
|
775
821
|
}
|
|
776
|
-
const path = drawShape.path;
|
|
822
|
+
const path = this.drawShape.path;
|
|
777
823
|
if (this.isDrawingPointerDown && !this.pointerIsDownAndPointerLeftDrawAreaWhenDown) {
|
|
778
824
|
path.addLine(e.point);
|
|
779
825
|
}
|
|
@@ -791,7 +837,8 @@ class DrawPad extends Composite {
|
|
|
791
837
|
this.strokes[strokeCount - 1].push({
|
|
792
838
|
type: DrawPadEventType.StrokeMove,
|
|
793
839
|
position: e.point,
|
|
794
|
-
iso8601Timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
840
|
+
iso8601Timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
841
|
+
interpolated: false
|
|
795
842
|
});
|
|
796
843
|
this.raiseDrawPadEvent(drawPadEvent);
|
|
797
844
|
}
|
|
@@ -820,11 +867,10 @@ class DrawPad extends Composite {
|
|
|
820
867
|
* Removes all strokes from the DrawPad.
|
|
821
868
|
*/
|
|
822
869
|
clear() {
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
throw new Error("no draw shape");
|
|
870
|
+
if (!this.drawShape?.path) {
|
|
871
|
+
throw new Error("DrawPad.clear(): no drawShape.path");
|
|
826
872
|
}
|
|
827
|
-
const path = drawShape.path;
|
|
873
|
+
const path = this.drawShape.path;
|
|
828
874
|
path.clear();
|
|
829
875
|
this.strokes = new Array();
|
|
830
876
|
}
|
|
@@ -874,45 +920,45 @@ class DrawPad extends Composite {
|
|
|
874
920
|
);
|
|
875
921
|
}
|
|
876
922
|
/**
|
|
877
|
-
* Adds
|
|
923
|
+
* Adds a node to the DrawPad.
|
|
878
924
|
*
|
|
879
|
-
* @remarks After the
|
|
925
|
+
* @remarks After the node is added to the DrawPad, its
|
|
880
926
|
* position is adjusted to be relative to the DrawPad's coordinate
|
|
881
927
|
* system, and it is made interactive. The method returns an object
|
|
882
|
-
* which is the
|
|
883
|
-
* properties, and events specific to it now being on a DrawPad. The
|
|
928
|
+
* which is the node as a DrawPadItem, which has additional methods,
|
|
929
|
+
* properties, and events specific to it now being on a DrawPad. The node
|
|
884
930
|
* now **must** be manipulated only using the DrawPadItem object. Using
|
|
885
|
-
* the original
|
|
931
|
+
* the original node object will result in undefined behavior.
|
|
886
932
|
*
|
|
887
|
-
* @param
|
|
888
|
-
* @returns the
|
|
933
|
+
* @param node - the node to add to the DrawPad
|
|
934
|
+
* @returns the node as a DrawPadItem
|
|
889
935
|
*/
|
|
890
|
-
addItem(
|
|
891
|
-
Object.defineProperty(
|
|
936
|
+
addItem(node) {
|
|
937
|
+
Object.defineProperty(node, "drawPadPosition", {
|
|
892
938
|
get: function() {
|
|
893
|
-
const drawPad =
|
|
939
|
+
const drawPad = node.parent;
|
|
894
940
|
return {
|
|
895
941
|
get x() {
|
|
896
|
-
return
|
|
942
|
+
return node.position.x + drawPad.size.width / 2;
|
|
897
943
|
},
|
|
898
944
|
set x(value) {
|
|
899
|
-
|
|
945
|
+
node.position.x = value - drawPad.size.width / 2;
|
|
900
946
|
},
|
|
901
947
|
get y() {
|
|
902
|
-
return
|
|
948
|
+
return node.position.y + drawPad.size.height / 2;
|
|
903
949
|
},
|
|
904
950
|
set y(value) {
|
|
905
|
-
|
|
951
|
+
node.position.y = value - drawPad.size.height / 2;
|
|
906
952
|
}
|
|
907
953
|
};
|
|
908
954
|
},
|
|
909
955
|
set: function(value) {
|
|
910
|
-
const drawPad =
|
|
911
|
-
|
|
912
|
-
|
|
956
|
+
const drawPad = node.parent;
|
|
957
|
+
node.position.x = value.x - drawPad.size.width / 2;
|
|
958
|
+
node.position.y = value.y - drawPad.size.height / 2;
|
|
913
959
|
}
|
|
914
960
|
});
|
|
915
|
-
Object.defineProperty(
|
|
961
|
+
Object.defineProperty(node, "onStrokeEnter", {
|
|
916
962
|
value: function(callback, options) {
|
|
917
963
|
this.addEventListener(
|
|
918
964
|
DrawPadItemEventType.StrokeEnter,
|
|
@@ -921,7 +967,7 @@ class DrawPad extends Composite {
|
|
|
921
967
|
);
|
|
922
968
|
}
|
|
923
969
|
});
|
|
924
|
-
Object.defineProperty(
|
|
970
|
+
Object.defineProperty(node, "onStrokeLeave", {
|
|
925
971
|
value: function(callback, options) {
|
|
926
972
|
this.addEventListener(
|
|
927
973
|
DrawPadItemEventType.StrokeLeave,
|
|
@@ -930,62 +976,62 @@ class DrawPad extends Composite {
|
|
|
930
976
|
);
|
|
931
977
|
}
|
|
932
978
|
});
|
|
933
|
-
Object.defineProperty(
|
|
979
|
+
Object.defineProperty(node, "isStrokeWithinBounds", {
|
|
934
980
|
value: false,
|
|
935
981
|
writable: true
|
|
936
982
|
});
|
|
937
|
-
|
|
983
|
+
node.onPointerDown(() => {
|
|
938
984
|
if (this.isDrawingPointerDown) {
|
|
939
|
-
if (
|
|
940
|
-
|
|
985
|
+
if (node.isStrokeWithinBounds === false) {
|
|
986
|
+
node.isStrokeWithinBounds = true;
|
|
941
987
|
const drawPadItemEvent = {
|
|
942
988
|
type: DrawPadItemEventType.StrokeEnter,
|
|
943
|
-
target:
|
|
989
|
+
target: node
|
|
944
990
|
};
|
|
945
|
-
this.raiseDrawPadItemEvent(
|
|
991
|
+
this.raiseDrawPadItemEvent(node, drawPadItemEvent);
|
|
946
992
|
}
|
|
947
993
|
}
|
|
948
994
|
});
|
|
949
|
-
|
|
995
|
+
node.onPointerMove(() => {
|
|
950
996
|
if (this.isDrawingPointerDown) {
|
|
951
|
-
if (
|
|
952
|
-
|
|
997
|
+
if (node.isStrokeWithinBounds === false) {
|
|
998
|
+
node.isStrokeWithinBounds = true;
|
|
953
999
|
const drawPadItemEvent = {
|
|
954
1000
|
type: DrawPadItemEventType.StrokeEnter,
|
|
955
|
-
target:
|
|
1001
|
+
target: node
|
|
956
1002
|
};
|
|
957
|
-
this.raiseDrawPadItemEvent(
|
|
1003
|
+
this.raiseDrawPadItemEvent(node, drawPadItemEvent);
|
|
958
1004
|
}
|
|
959
1005
|
}
|
|
960
1006
|
});
|
|
961
|
-
|
|
1007
|
+
node.onPointerLeave(() => {
|
|
962
1008
|
if (this.isDrawingPointerDown) {
|
|
963
|
-
if (
|
|
964
|
-
|
|
1009
|
+
if (node.isStrokeWithinBounds === true) {
|
|
1010
|
+
node.isStrokeWithinBounds = false;
|
|
965
1011
|
const drawPadItemEvent = {
|
|
966
1012
|
type: DrawPadItemEventType.StrokeLeave,
|
|
967
|
-
target:
|
|
1013
|
+
target: node
|
|
968
1014
|
};
|
|
969
|
-
this.raiseDrawPadItemEvent(
|
|
1015
|
+
this.raiseDrawPadItemEvent(node, drawPadItemEvent);
|
|
970
1016
|
}
|
|
971
1017
|
}
|
|
972
1018
|
});
|
|
973
|
-
|
|
974
|
-
if (
|
|
975
|
-
|
|
1019
|
+
node.onPointerUp(() => {
|
|
1020
|
+
if (node.isStrokeWithinBounds === true) {
|
|
1021
|
+
node.isStrokeWithinBounds = false;
|
|
976
1022
|
const drawPadItemEvent = {
|
|
977
1023
|
type: DrawPadItemEventType.StrokeLeave,
|
|
978
|
-
target:
|
|
1024
|
+
target: node
|
|
979
1025
|
};
|
|
980
|
-
this.raiseDrawPadItemEvent(
|
|
1026
|
+
this.raiseDrawPadItemEvent(node, drawPadItemEvent);
|
|
981
1027
|
}
|
|
982
1028
|
});
|
|
983
|
-
this.addChild(
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
return
|
|
1029
|
+
this.addChild(node);
|
|
1030
|
+
node.zPosition = -1;
|
|
1031
|
+
node.position.x = node.position.x - this.size.width / 2;
|
|
1032
|
+
node.position.y = node.position.y - this.size.height / 2;
|
|
1033
|
+
node.isUserInteractionEnabled = true;
|
|
1034
|
+
return node;
|
|
989
1035
|
}
|
|
990
1036
|
/**
|
|
991
1037
|
* Takes a screenshot of the DrawPad.
|
|
@@ -994,13 +1040,9 @@ class DrawPad extends Composite {
|
|
|
994
1040
|
* PNG format.
|
|
995
1041
|
*/
|
|
996
1042
|
takeScreenshot() {
|
|
997
|
-
const surface = this.game.surface;
|
|
998
|
-
if (!surface) {
|
|
999
|
-
throw new Error("no surface");
|
|
1000
|
-
}
|
|
1001
1043
|
const drawArea = this.drawArea;
|
|
1002
1044
|
if (!drawArea) {
|
|
1003
|
-
throw new Error("no
|
|
1045
|
+
throw new Error("DrawPad.takeScreenshot(): no drawArea");
|
|
1004
1046
|
}
|
|
1005
1047
|
const sx = (drawArea.absolutePosition.x - drawArea.size.width / 2) * Globals.canvasScale;
|
|
1006
1048
|
const sy = (drawArea.absolutePosition.y - drawArea.size.height / 2) * Globals.canvasScale;
|
|
@@ -1021,15 +1063,85 @@ class DrawPad extends Composite {
|
|
|
1021
1063
|
pixelData.length / sh
|
|
1022
1064
|
);
|
|
1023
1065
|
if (!croppedImage) {
|
|
1024
|
-
throw new Error("no
|
|
1066
|
+
throw new Error("DrawPad.takeScreenshot(): no croppedImage");
|
|
1025
1067
|
}
|
|
1026
1068
|
const bytes = croppedImage.encodeToBytes();
|
|
1027
1069
|
if (!bytes) {
|
|
1028
|
-
throw new Error(
|
|
1070
|
+
throw new Error(
|
|
1071
|
+
"DrawPad.takeScreenshot(): croppedImage.encodeToBytes() failed"
|
|
1072
|
+
);
|
|
1029
1073
|
}
|
|
1030
1074
|
croppedImage.delete();
|
|
1031
1075
|
return this.arrayBufferToBase64String(bytes);
|
|
1032
1076
|
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Determines whether a point is within the DrawPad.
|
|
1079
|
+
*
|
|
1080
|
+
* @param point - The point to check
|
|
1081
|
+
* @returns True - if the point is within the DrawPad, false otherwise
|
|
1082
|
+
*/
|
|
1083
|
+
isPointWithinDrawPad(point, drawPadSize) {
|
|
1084
|
+
return point.x >= 0 && point.x <= drawPadSize.width && point.y >= 0 && point.y <= drawPadSize.height;
|
|
1085
|
+
}
|
|
1086
|
+
/**
|
|
1087
|
+
* Interpolates a point to the border of the DrawPad based on a line that
|
|
1088
|
+
* crosses the DrawPad border. The line is formed by the current "out of
|
|
1089
|
+
* bounds" point the and previous "within bounds" point.
|
|
1090
|
+
*
|
|
1091
|
+
* @param currentPoint - The current point
|
|
1092
|
+
* @param previousPoint - The previous point
|
|
1093
|
+
* @param drawPadSize - The size of the DrawPad
|
|
1094
|
+
* @returns A new point on the border of the DrawPad
|
|
1095
|
+
*/
|
|
1096
|
+
interpolateToDrawPadBorder(currentPoint, previousPoint, drawPadSize) {
|
|
1097
|
+
const slope = (currentPoint.y - previousPoint.y) / (currentPoint.x - previousPoint.x);
|
|
1098
|
+
const intercept = currentPoint.y - slope * currentPoint.x;
|
|
1099
|
+
const newPoint = { x: 0, y: 0 };
|
|
1100
|
+
if (!Number.isFinite(slope)) {
|
|
1101
|
+
newPoint.x = currentPoint.x;
|
|
1102
|
+
if (currentPoint.y - previousPoint.y > 0) {
|
|
1103
|
+
newPoint.y = drawPadSize.height;
|
|
1104
|
+
return newPoint;
|
|
1105
|
+
}
|
|
1106
|
+
if (currentPoint.y - previousPoint.y < 0) {
|
|
1107
|
+
newPoint.y = 0;
|
|
1108
|
+
return newPoint;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
const yLeft = slope * 0 + intercept;
|
|
1112
|
+
const yRight = slope * drawPadSize.width + intercept;
|
|
1113
|
+
if (yLeft >= 0 && yLeft <= drawPadSize.height) {
|
|
1114
|
+
if (currentPoint.x - previousPoint.x < 0) {
|
|
1115
|
+
newPoint.x = 0;
|
|
1116
|
+
newPoint.y = yLeft;
|
|
1117
|
+
return newPoint;
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
if (yRight >= 0 && yRight <= drawPadSize.height) {
|
|
1121
|
+
if (currentPoint.x - previousPoint.x > 0) {
|
|
1122
|
+
newPoint.x = drawPadSize.width;
|
|
1123
|
+
newPoint.y = yRight;
|
|
1124
|
+
return newPoint;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
const xTop = (0 - intercept) / slope;
|
|
1128
|
+
const xBottom = (drawPadSize.height - intercept) / slope;
|
|
1129
|
+
if (xTop >= 0 && xTop <= drawPadSize.width) {
|
|
1130
|
+
if (currentPoint.y - previousPoint.y < 0) {
|
|
1131
|
+
newPoint.x = xTop;
|
|
1132
|
+
newPoint.y = 0;
|
|
1133
|
+
return newPoint;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
if (xBottom >= 0 && xBottom <= drawPadSize.width) {
|
|
1137
|
+
if (currentPoint.y - previousPoint.y > 0) {
|
|
1138
|
+
newPoint.x = xBottom;
|
|
1139
|
+
newPoint.y = drawPadSize.height;
|
|
1140
|
+
return newPoint;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
return currentPoint;
|
|
1144
|
+
}
|
|
1033
1145
|
arrayBufferToBase64String(buffer) {
|
|
1034
1146
|
let binary = "";
|
|
1035
1147
|
const bytes = new Uint8Array(buffer);
|
|
@@ -1074,7 +1186,7 @@ class DrawPad extends Composite {
|
|
|
1074
1186
|
this.needsInitialization = true;
|
|
1075
1187
|
}
|
|
1076
1188
|
duplicate(newName) {
|
|
1077
|
-
throw new Error("Method not implemented.");
|
|
1189
|
+
throw new Error("DrawPad.duplicate(): Method not implemented.");
|
|
1078
1190
|
}
|
|
1079
1191
|
}
|
|
1080
1192
|
|
|
@@ -1345,10 +1457,10 @@ class VirtualKeyboard extends Composite {
|
|
|
1345
1457
|
letterCircle.hidden = true;
|
|
1346
1458
|
if (this.eventListeners.length > 0) {
|
|
1347
1459
|
this.eventListeners.filter(
|
|
1348
|
-
(listener) => listener.type ===
|
|
1460
|
+
(listener) => listener.type === M2EventType.CompositeCustom && listener.compositeType === "VirtualKeyboardKeyUp"
|
|
1349
1461
|
).forEach((listener) => {
|
|
1350
1462
|
const virtualKeyboardEvent = {
|
|
1351
|
-
type:
|
|
1463
|
+
type: M2EventType.CompositeCustom,
|
|
1352
1464
|
target: this,
|
|
1353
1465
|
handled: false,
|
|
1354
1466
|
key: keyAsString,
|
|
@@ -1413,10 +1525,10 @@ class VirtualKeyboard extends Composite {
|
|
|
1413
1525
|
}
|
|
1414
1526
|
if (this.eventListeners.length > 0) {
|
|
1415
1527
|
this.eventListeners.filter(
|
|
1416
|
-
(listener) => listener.type ===
|
|
1528
|
+
(listener) => listener.type === M2EventType.CompositeCustom && listener.compositeType === "VirtualKeyboardKeyDown"
|
|
1417
1529
|
).forEach((listener) => {
|
|
1418
1530
|
const virtualKeyboardEvent = {
|
|
1419
|
-
type:
|
|
1531
|
+
type: M2EventType.CompositeCustom,
|
|
1420
1532
|
target: this,
|
|
1421
1533
|
handled: false,
|
|
1422
1534
|
key: keyAsString,
|
|
@@ -1470,50 +1582,36 @@ class VirtualKeyboard extends Composite {
|
|
|
1470
1582
|
* Executes a callback when the user presses down on a key.
|
|
1471
1583
|
*
|
|
1472
1584
|
* @param callback - function to execute
|
|
1473
|
-
* @param
|
|
1474
|
-
* any existing callbacks of the same event type on this entity? Usually
|
|
1475
|
-
* there should be only one callback defined, instead of chaining multiple
|
|
1476
|
-
* ones. It is strongly recommended not to change this, unless you have a
|
|
1477
|
-
* special use case. Default is true.
|
|
1585
|
+
* @param options
|
|
1478
1586
|
*/
|
|
1479
|
-
onKeyDown(callback,
|
|
1587
|
+
onKeyDown(callback, options) {
|
|
1480
1588
|
const eventListener = {
|
|
1481
|
-
type:
|
|
1589
|
+
type: M2EventType.CompositeCustom,
|
|
1482
1590
|
compositeType: "VirtualKeyboardKeyDown",
|
|
1483
|
-
|
|
1591
|
+
nodeUuid: this.uuid,
|
|
1484
1592
|
callback
|
|
1485
1593
|
};
|
|
1486
|
-
this.addVirtualKeyboardEventListener(
|
|
1487
|
-
replaceExistingCallback,
|
|
1488
|
-
eventListener
|
|
1489
|
-
);
|
|
1594
|
+
this.addVirtualKeyboardEventListener(eventListener, options);
|
|
1490
1595
|
}
|
|
1491
1596
|
/**
|
|
1492
1597
|
* Executes a callback when the user releases a key.
|
|
1493
1598
|
*
|
|
1494
1599
|
* @param callback - function to execute
|
|
1495
|
-
* @param
|
|
1496
|
-
* any existing callbacks of the same event type on this entity? Usually
|
|
1497
|
-
* there should be only one callback defined, instead of chaining multiple
|
|
1498
|
-
* ones. It is strongly recommended not to change this, unless you have a
|
|
1499
|
-
* special use case. Default is true.
|
|
1600
|
+
* @param options
|
|
1500
1601
|
*/
|
|
1501
|
-
onKeyUp(callback,
|
|
1602
|
+
onKeyUp(callback, options) {
|
|
1502
1603
|
const eventListener = {
|
|
1503
|
-
type:
|
|
1604
|
+
type: M2EventType.CompositeCustom,
|
|
1504
1605
|
compositeType: "VirtualKeyboardKeyUp",
|
|
1505
|
-
|
|
1606
|
+
nodeUuid: this.uuid,
|
|
1506
1607
|
callback
|
|
1507
1608
|
};
|
|
1508
|
-
this.addVirtualKeyboardEventListener(
|
|
1509
|
-
replaceExistingCallback,
|
|
1510
|
-
eventListener
|
|
1511
|
-
);
|
|
1609
|
+
this.addVirtualKeyboardEventListener(eventListener, options);
|
|
1512
1610
|
}
|
|
1513
|
-
addVirtualKeyboardEventListener(
|
|
1514
|
-
if (
|
|
1611
|
+
addVirtualKeyboardEventListener(eventListener, options) {
|
|
1612
|
+
if (options?.replaceExisting) {
|
|
1515
1613
|
this.eventListeners = this.eventListeners.filter(
|
|
1516
|
-
(listener) => !(listener.
|
|
1614
|
+
(listener) => !(listener.nodeUuid === eventListener.nodeUuid && listener.type === eventListener.type && listener.compositeType === eventListener.compositeType)
|
|
1517
1615
|
);
|
|
1518
1616
|
}
|
|
1519
1617
|
this.eventListeners.push(eventListener);
|
|
@@ -1535,27 +1633,27 @@ class VirtualKeyboard extends Composite {
|
|
|
1535
1633
|
}
|
|
1536
1634
|
}
|
|
1537
1635
|
|
|
1538
|
-
const SCENE_TRANSITION_EASING = Easings.sinusoidalInOut;
|
|
1636
|
+
const SCENE_TRANSITION_EASING$1 = Easings.sinusoidalInOut;
|
|
1539
1637
|
const SCENE_TRANSITION_DURATION = 500;
|
|
1540
1638
|
class Instructions extends Story {
|
|
1541
1639
|
/**
|
|
1542
|
-
*
|
|
1640
|
+
* Creates an array of scenes containing instructions on how to complete the assessment
|
|
1543
1641
|
*
|
|
1544
1642
|
* @param options - {@link InstructionsOptions}
|
|
1545
|
-
* @returns
|
|
1643
|
+
* @returns instruction scenes
|
|
1546
1644
|
*/
|
|
1547
|
-
static
|
|
1645
|
+
static create(options) {
|
|
1548
1646
|
const scenes = new Array();
|
|
1549
1647
|
options.instructionScenes.forEach((s, i) => {
|
|
1550
1648
|
const nextSceneTransition = s.nextSceneTransition ?? options.nextSceneTransition ?? Transition.slide({
|
|
1551
1649
|
direction: TransitionDirection.Left,
|
|
1552
1650
|
duration: SCENE_TRANSITION_DURATION,
|
|
1553
|
-
easing: SCENE_TRANSITION_EASING
|
|
1651
|
+
easing: SCENE_TRANSITION_EASING$1
|
|
1554
1652
|
});
|
|
1555
1653
|
const backSceneTransition = s.backSceneTransition ?? options.backSceneTransition ?? Transition.slide({
|
|
1556
1654
|
direction: TransitionDirection.Right,
|
|
1557
1655
|
duration: SCENE_TRANSITION_DURATION,
|
|
1558
|
-
easing: SCENE_TRANSITION_EASING
|
|
1656
|
+
easing: SCENE_TRANSITION_EASING$1
|
|
1559
1657
|
});
|
|
1560
1658
|
const backButtonText = s.backButtonText ?? options.backButtonText ?? "Back";
|
|
1561
1659
|
const nextButtonText = s.nextButtonText ?? options.nextButtonText ?? "Next";
|
|
@@ -1740,9 +1838,150 @@ class Instructions extends Story {
|
|
|
1740
1838
|
});
|
|
1741
1839
|
return scenes;
|
|
1742
1840
|
}
|
|
1841
|
+
/**
|
|
1842
|
+
* Creates an array of scenes containing instructions on how to complete the assessment
|
|
1843
|
+
*
|
|
1844
|
+
* @deprecated Use {@link Instructions.create} instead (lower case method name "create")
|
|
1845
|
+
*
|
|
1846
|
+
* @param options - {@link InstructionsOptions}
|
|
1847
|
+
* @returns instruction scenes
|
|
1848
|
+
*/
|
|
1849
|
+
static Create(options) {
|
|
1850
|
+
return this.create(options);
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
const SCENE_TRANSITION_EASING = Easings.sinusoidalInOut;
|
|
1855
|
+
const SCENE_TRANSITION_DURATION_MS = 500;
|
|
1856
|
+
class CountdownScene extends Scene {
|
|
1857
|
+
/**
|
|
1858
|
+
* A scene that counts down from a specified number to zero, then transitions to the next scene.
|
|
1859
|
+
*
|
|
1860
|
+
* @param options - {@link CountdownSceneOptions}
|
|
1861
|
+
*/
|
|
1862
|
+
constructor(options) {
|
|
1863
|
+
super(options);
|
|
1864
|
+
if (options?.transitionDurationMilliseconds !== void 0 && options?.transition) {
|
|
1865
|
+
throw new Error(
|
|
1866
|
+
"Both transition and transitionDurationMilliseconds options were provided. Only one should be provided. If using a custom transition, then the duration of that transition must be specified within the custom transition."
|
|
1867
|
+
);
|
|
1868
|
+
}
|
|
1869
|
+
let timerShape;
|
|
1870
|
+
if (options?.timerShape?.circle === void 0 && options?.timerShape?.rectangle === void 0 || options?.timerShape.circle !== void 0) {
|
|
1871
|
+
timerShape = new Shape({
|
|
1872
|
+
circleOfRadius: options?.timerShape?.circle?.radius ?? 100,
|
|
1873
|
+
layout: {
|
|
1874
|
+
constraints: {
|
|
1875
|
+
topToTopOf: this,
|
|
1876
|
+
bottomToBottomOf: this,
|
|
1877
|
+
startToStartOf: this,
|
|
1878
|
+
endToEndOf: this,
|
|
1879
|
+
verticalBias: options?.timerShape?.verticalBias ?? 0.5
|
|
1880
|
+
}
|
|
1881
|
+
},
|
|
1882
|
+
fillColor: options?.timerShape?.fillColor ?? WebColors.RoyalBlue
|
|
1883
|
+
});
|
|
1884
|
+
this.addChild(timerShape);
|
|
1885
|
+
} else if (options?.timerShape.rectangle !== void 0) {
|
|
1886
|
+
timerShape = new Shape({
|
|
1887
|
+
rect: {
|
|
1888
|
+
width: options?.timerShape?.rectangle?.width ?? 200,
|
|
1889
|
+
height: options?.timerShape?.rectangle?.height ?? 200
|
|
1890
|
+
},
|
|
1891
|
+
cornerRadius: options?.timerShape?.rectangle?.cornerRadius,
|
|
1892
|
+
layout: {
|
|
1893
|
+
constraints: {
|
|
1894
|
+
topToTopOf: this,
|
|
1895
|
+
bottomToBottomOf: this,
|
|
1896
|
+
startToStartOf: this,
|
|
1897
|
+
endToEndOf: this,
|
|
1898
|
+
verticalBias: options?.timerShape?.verticalBias ?? 0.5
|
|
1899
|
+
}
|
|
1900
|
+
},
|
|
1901
|
+
fillColor: options?.timerShape?.fillColor ?? WebColors.RoyalBlue
|
|
1902
|
+
});
|
|
1903
|
+
this.addChild(timerShape);
|
|
1904
|
+
} else {
|
|
1905
|
+
throw new Error("Invalid timer shape options.");
|
|
1906
|
+
}
|
|
1907
|
+
const timerInitialNumber = Math.floor(options.milliseconds / 1e3);
|
|
1908
|
+
const timerNumberLabel = new Label({
|
|
1909
|
+
// Number text will be set in onSetup()
|
|
1910
|
+
text: "",
|
|
1911
|
+
fontSize: options?.timerNumbersFontSize ?? 50,
|
|
1912
|
+
fontName: options?.timerNumbersFontName,
|
|
1913
|
+
fontColor: options?.timerNumbersFontColor ?? WebColors.White
|
|
1914
|
+
});
|
|
1915
|
+
timerShape.addChild(timerNumberLabel);
|
|
1916
|
+
const textLabel = new Label({
|
|
1917
|
+
text: options?.text ?? "GET READY",
|
|
1918
|
+
fontSize: options?.textFontSize ?? 50,
|
|
1919
|
+
fontName: options?.textFontName,
|
|
1920
|
+
fontColor: options?.textFontColor,
|
|
1921
|
+
layout: {
|
|
1922
|
+
marginTop: options?.textMarginTop ?? 32,
|
|
1923
|
+
constraints: {
|
|
1924
|
+
topToBottomOf: timerShape,
|
|
1925
|
+
startToStartOf: this,
|
|
1926
|
+
endToEndOf: this
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
});
|
|
1930
|
+
this.addChild(textLabel);
|
|
1931
|
+
const countdownSequence = new Array();
|
|
1932
|
+
for (let i = timerInitialNumber - 1; i > 0; i--) {
|
|
1933
|
+
countdownSequence.push(Action.wait({ duration: 1e3 }));
|
|
1934
|
+
countdownSequence.push(
|
|
1935
|
+
Action.custom({
|
|
1936
|
+
callback: () => {
|
|
1937
|
+
timerNumberLabel.text = i.toString();
|
|
1938
|
+
}
|
|
1939
|
+
})
|
|
1940
|
+
);
|
|
1941
|
+
}
|
|
1942
|
+
countdownSequence.push(Action.wait({ duration: 1e3 }));
|
|
1943
|
+
countdownSequence.push(
|
|
1944
|
+
Action.custom({
|
|
1945
|
+
callback: () => {
|
|
1946
|
+
timerNumberLabel.text = options?.timerZeroString ?? "0";
|
|
1947
|
+
}
|
|
1948
|
+
})
|
|
1949
|
+
);
|
|
1950
|
+
if (options?.zeroDwellMilliseconds !== void 0) {
|
|
1951
|
+
countdownSequence.push(
|
|
1952
|
+
Action.wait({ duration: options.zeroDwellMilliseconds })
|
|
1953
|
+
);
|
|
1954
|
+
}
|
|
1955
|
+
countdownSequence.push(
|
|
1956
|
+
Action.custom({
|
|
1957
|
+
callback: () => {
|
|
1958
|
+
const game = this.game;
|
|
1959
|
+
const isLastScene = game.scenes.indexOf(this) === game.scenes.length - 1;
|
|
1960
|
+
if (isLastScene) {
|
|
1961
|
+
game.end();
|
|
1962
|
+
}
|
|
1963
|
+
const nextScene = game.scenes[game.scenes.indexOf(this) + 1];
|
|
1964
|
+
game.presentScene(
|
|
1965
|
+
nextScene,
|
|
1966
|
+
options?.transition ?? Transition.slide({
|
|
1967
|
+
direction: TransitionDirection.Left,
|
|
1968
|
+
duration: options?.transitionDurationMilliseconds ?? SCENE_TRANSITION_DURATION_MS,
|
|
1969
|
+
easing: SCENE_TRANSITION_EASING
|
|
1970
|
+
})
|
|
1971
|
+
);
|
|
1972
|
+
}
|
|
1973
|
+
})
|
|
1974
|
+
);
|
|
1975
|
+
this.onSetup(() => {
|
|
1976
|
+
timerNumberLabel.text = timerInitialNumber.toString();
|
|
1977
|
+
});
|
|
1978
|
+
this.onAppear(() => {
|
|
1979
|
+
this.run(Action.sequence(countdownSequence));
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1743
1982
|
}
|
|
1744
1983
|
|
|
1745
|
-
console.log("\u26AA @m2c2kit/addons version 0.3.
|
|
1984
|
+
console.log("\u26AA @m2c2kit/addons version 0.3.14 (ebbdc605)");
|
|
1746
1985
|
|
|
1747
|
-
export { Button, Dialog, DialogResult, DrawPad, DrawPadEventType, DrawPadItemEventType, Grid, Instructions, VirtualKeyboard };
|
|
1986
|
+
export { Button, CountdownScene, Dialog, DialogResult, DrawPad, DrawPadEventType, DrawPadItemEventType, Grid, Instructions, VirtualKeyboard };
|
|
1748
1987
|
//# sourceMappingURL=index.js.map
|