@leafer-ui/core 1.0.0-rc.2 → 1.0.0-rc.20

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/lib/core.cjs ADDED
@@ -0,0 +1,1501 @@
1
+ 'use strict';
2
+
3
+ var draw = require('@leafer-ui/draw');
4
+ var core = require('@leafer/core');
5
+
6
+ /******************************************************************************
7
+ Copyright (c) Microsoft Corporation.
8
+
9
+ Permission to use, copy, modify, and/or distribute this software for any
10
+ purpose with or without fee is hereby granted.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
13
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
14
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
15
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
17
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18
+ PERFORMANCE OF THIS SOFTWARE.
19
+ ***************************************************************************** */
20
+ /* global Reflect, Promise, SuppressedError, Symbol */
21
+
22
+
23
+ function __decorate(decorators, target, key, desc) {
24
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
25
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
26
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
27
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
28
+ }
29
+
30
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
31
+ var e = new Error(message);
32
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
33
+ };
34
+
35
+ exports.App = class App extends draw.Leafer {
36
+ get __tag() { return 'App'; }
37
+ get isApp() { return true; }
38
+ constructor(userConfig, data) {
39
+ super(userConfig, data);
40
+ }
41
+ init(userConfig, parentApp) {
42
+ super.init(userConfig, parentApp);
43
+ if (userConfig) {
44
+ const { ground, tree, sky, editor } = userConfig;
45
+ if (ground)
46
+ this.ground = this.addLeafer(ground);
47
+ if (tree || editor)
48
+ this.tree = this.addLeafer(tree);
49
+ if (sky || editor)
50
+ this.sky = this.addLeafer(sky || { type: 'draw', usePartRender: false });
51
+ if (editor) {
52
+ this.editor = core.Creator.editor(editor);
53
+ this.sky.add(this.editor);
54
+ }
55
+ }
56
+ }
57
+ __setApp() {
58
+ const { canvas } = this;
59
+ const { realCanvas, view } = this.config;
60
+ if (realCanvas || view === this.canvas.view || !canvas.parentView) {
61
+ this.realCanvas = true;
62
+ }
63
+ else {
64
+ canvas.unrealCanvas();
65
+ }
66
+ this.leafer = this;
67
+ this.watcher.disable();
68
+ this.layouter.disable();
69
+ this.__eventIds.push(this.on_(core.PropertyEvent.CHANGE, this.__onPropertyChange, this));
70
+ }
71
+ start() {
72
+ super.start();
73
+ this.children.forEach(leafer => leafer.start());
74
+ }
75
+ stop() {
76
+ this.children.forEach(leafer => leafer.stop());
77
+ super.stop();
78
+ }
79
+ unlockLayout() {
80
+ super.unlockLayout();
81
+ this.children.forEach(leafer => leafer.unlockLayout());
82
+ }
83
+ lockLayout() {
84
+ super.lockLayout();
85
+ this.children.forEach(leafer => leafer.lockLayout());
86
+ }
87
+ forceRender(bounds) {
88
+ this.children.forEach(leafer => leafer.forceRender(bounds));
89
+ }
90
+ addLeafer(merge) {
91
+ const leafer = new draw.Leafer(merge);
92
+ this.add(leafer);
93
+ return leafer;
94
+ }
95
+ add(leafer) {
96
+ if (!leafer.view) {
97
+ if (this.realCanvas && !this.canvas.bounds) {
98
+ setTimeout(() => this.add(leafer), 10);
99
+ return;
100
+ }
101
+ leafer.init(this.__getChildConfig(leafer.userConfig), this);
102
+ }
103
+ super.add(leafer);
104
+ this.__listenChildEvents(leafer);
105
+ }
106
+ __onPropertyChange() {
107
+ if (core.Debug.showHitView)
108
+ this.children.forEach(leafer => leafer.forceUpdate('surface'));
109
+ }
110
+ __onCreated() {
111
+ this.created = this.children.every(child => child.created);
112
+ }
113
+ __onReady() {
114
+ if (this.children.every(child => child.ready))
115
+ super.__onReady();
116
+ }
117
+ __onViewReady() {
118
+ if (this.children.every(child => child.viewReady))
119
+ super.__onViewReady();
120
+ }
121
+ __onChildRenderEnd(e) {
122
+ this.renderer.addBlock(e.renderBounds);
123
+ if (this.viewReady)
124
+ this.renderer.update();
125
+ }
126
+ __render(canvas, options) {
127
+ canvas.setWorld(options.matrix || this.__world);
128
+ this.children.forEach(leafer => canvas.copyWorld(leafer.canvas));
129
+ }
130
+ __onResize(event) {
131
+ this.children.forEach(leafer => leafer.resize(event));
132
+ super.__onResize(event);
133
+ }
134
+ __checkUpdateLayout() {
135
+ this.children.forEach(leafer => leafer.__layout.update());
136
+ }
137
+ __getChildConfig(userConfig) {
138
+ let config = Object.assign({}, this.config);
139
+ config.hittable = config.realCanvas = undefined;
140
+ if (userConfig)
141
+ core.DataHelper.assign(config, userConfig);
142
+ if (this.autoLayout)
143
+ core.DataHelper.copyAttrs(config, this, core.canvasSizeAttrs);
144
+ config.view = this.realCanvas ? undefined : this.view;
145
+ config.fill = undefined;
146
+ return config;
147
+ }
148
+ __listenChildEvents(leafer) {
149
+ leafer.once(core.LayoutEvent.END, () => this.__onReady());
150
+ leafer.once(core.RenderEvent.START, () => this.__onCreated());
151
+ leafer.once(core.RenderEvent.END, () => this.__onViewReady());
152
+ if (this.realCanvas)
153
+ this.__eventIds.push(leafer.on_(core.RenderEvent.END, this.__onChildRenderEnd, this));
154
+ }
155
+ };
156
+ exports.App = __decorate([
157
+ core.registerUI()
158
+ ], exports.App);
159
+
160
+ const downKeyMap = {};
161
+ const Keyboard = {
162
+ isHoldSpaceKey() {
163
+ return Keyboard.isHold('Space');
164
+ },
165
+ isHold(code) {
166
+ return downKeyMap[code];
167
+ },
168
+ setDownCode(code) {
169
+ if (!downKeyMap[code])
170
+ downKeyMap[code] = true;
171
+ },
172
+ setUpCode(code) {
173
+ downKeyMap[code] = false;
174
+ }
175
+ };
176
+
177
+ const PointerButton = {
178
+ LEFT: 1,
179
+ RIGHT: 2,
180
+ MIDDLE: 4,
181
+ defaultLeft(event) { if (!event.buttons)
182
+ event.buttons = 1; },
183
+ left(event) { return event.buttons === 1; },
184
+ right(event) { return event.buttons === 2; },
185
+ middle(event) { return event.buttons === 4; }
186
+ };
187
+
188
+ class UIEvent extends core.Event {
189
+ get spaceKey() { return Keyboard.isHoldSpaceKey(); }
190
+ get left() { return PointerButton.left(this); }
191
+ get right() { return PointerButton.right(this); }
192
+ get middle() { return PointerButton.middle(this); }
193
+ constructor(params) {
194
+ super(params.type);
195
+ this.bubbles = true;
196
+ Object.assign(this, params);
197
+ }
198
+ getPage() {
199
+ return this.current.getPagePoint(this);
200
+ }
201
+ getInner(relative) {
202
+ if (!relative)
203
+ relative = this.current;
204
+ return relative.getInnerPoint(this);
205
+ }
206
+ getLocal(relative) {
207
+ if (!relative)
208
+ relative = this.current;
209
+ return relative.getLocalPoint(this);
210
+ }
211
+ static changeName(oldName, newName) {
212
+ core.EventCreator.changeName(oldName, newName);
213
+ }
214
+ }
215
+
216
+ exports.PointerEvent = class PointerEvent extends UIEvent {
217
+ };
218
+ exports.PointerEvent.POINTER = 'pointer';
219
+ exports.PointerEvent.BEFORE_DOWN = 'pointer.before_down';
220
+ exports.PointerEvent.BEFORE_MOVE = 'pointer.before_move';
221
+ exports.PointerEvent.BEFORE_UP = 'pointer.before_up';
222
+ exports.PointerEvent.DOWN = 'pointer.down';
223
+ exports.PointerEvent.MOVE = 'pointer.move';
224
+ exports.PointerEvent.UP = 'pointer.up';
225
+ exports.PointerEvent.OVER = 'pointer.over';
226
+ exports.PointerEvent.OUT = 'pointer.out';
227
+ exports.PointerEvent.ENTER = 'pointer.enter';
228
+ exports.PointerEvent.LEAVE = 'pointer.leave';
229
+ exports.PointerEvent.TAP = 'tap';
230
+ exports.PointerEvent.DOUBLE_TAP = 'double_tap';
231
+ exports.PointerEvent.CLICK = 'click';
232
+ exports.PointerEvent.DOUBLE_CLICK = 'double_click';
233
+ exports.PointerEvent.LONG_PRESS = 'long_press';
234
+ exports.PointerEvent.LONG_TAP = 'long_tap';
235
+ exports.PointerEvent.MENU = 'pointer.menu';
236
+ exports.PointerEvent.MENU_TAP = 'pointer.menu_tap';
237
+ exports.PointerEvent = __decorate([
238
+ core.registerUIEvent()
239
+ ], exports.PointerEvent);
240
+
241
+ const move = {};
242
+ exports.DragEvent = class DragEvent extends exports.PointerEvent {
243
+ static setList(data) {
244
+ this.list = data instanceof core.LeafList ? data : new core.LeafList(data);
245
+ }
246
+ static setData(data) {
247
+ this.data = data;
248
+ }
249
+ getPageMove(total) {
250
+ this.assignMove(total);
251
+ return this.current.getPagePoint(move, null, true);
252
+ }
253
+ getInnerMove(relative, total) {
254
+ if (!relative)
255
+ relative = this.current;
256
+ this.assignMove(total);
257
+ return relative.getInnerPoint(move, null, true);
258
+ }
259
+ getLocalMove(relative, total) {
260
+ if (!relative)
261
+ relative = this.current;
262
+ this.assignMove(total);
263
+ return relative.getLocalPoint(move, null, true);
264
+ }
265
+ getPageTotal() {
266
+ return this.getPageMove(true);
267
+ }
268
+ getInnerTotal(relative) {
269
+ return this.getInnerMove(relative, true);
270
+ }
271
+ getLocalTotal(relative) {
272
+ return this.getLocalMove(relative, true);
273
+ }
274
+ assignMove(total) {
275
+ move.x = total ? this.totalX : this.moveX;
276
+ move.y = total ? this.totalY : this.moveY;
277
+ }
278
+ };
279
+ exports.DragEvent.BEFORE_DRAG = 'drag.before_drag';
280
+ exports.DragEvent.START = 'drag.start';
281
+ exports.DragEvent.DRAG = 'drag';
282
+ exports.DragEvent.END = 'drag.end';
283
+ exports.DragEvent.OVER = 'drag.over';
284
+ exports.DragEvent.OUT = 'drag.out';
285
+ exports.DragEvent.ENTER = 'drag.enter';
286
+ exports.DragEvent.LEAVE = 'drag.leave';
287
+ exports.DragEvent = __decorate([
288
+ core.registerUIEvent()
289
+ ], exports.DragEvent);
290
+
291
+ exports.DropEvent = class DropEvent extends exports.PointerEvent {
292
+ static setList(data) {
293
+ exports.DragEvent.setList(data);
294
+ }
295
+ static setData(data) {
296
+ exports.DragEvent.setData(data);
297
+ }
298
+ };
299
+ exports.DropEvent.DROP = 'drop';
300
+ exports.DropEvent = __decorate([
301
+ core.registerUIEvent()
302
+ ], exports.DropEvent);
303
+
304
+ exports.MoveEvent = class MoveEvent extends exports.DragEvent {
305
+ };
306
+ exports.MoveEvent.BEFORE_MOVE = 'move.before_move';
307
+ exports.MoveEvent.START = 'move.start';
308
+ exports.MoveEvent.MOVE = 'move';
309
+ exports.MoveEvent.END = 'move.end';
310
+ exports.MoveEvent = __decorate([
311
+ core.registerUIEvent()
312
+ ], exports.MoveEvent);
313
+
314
+ exports.RotateEvent = class RotateEvent extends UIEvent {
315
+ };
316
+ exports.RotateEvent.BEFORE_ROTATE = 'rotate.before_rotate';
317
+ exports.RotateEvent.START = 'rotate.start';
318
+ exports.RotateEvent.ROTATE = 'rotate';
319
+ exports.RotateEvent.END = 'rotate.end';
320
+ exports.RotateEvent = __decorate([
321
+ core.registerUIEvent()
322
+ ], exports.RotateEvent);
323
+
324
+ exports.SwipeEvent = class SwipeEvent extends exports.DragEvent {
325
+ };
326
+ exports.SwipeEvent.SWIPE = 'swipe';
327
+ exports.SwipeEvent.LEFT = 'swipe.left';
328
+ exports.SwipeEvent.RIGHT = 'swipe.right';
329
+ exports.SwipeEvent.UP = 'swipe.up';
330
+ exports.SwipeEvent.DOWN = 'swipe.down';
331
+ exports.SwipeEvent = __decorate([
332
+ core.registerUIEvent()
333
+ ], exports.SwipeEvent);
334
+
335
+ exports.ZoomEvent = class ZoomEvent extends UIEvent {
336
+ };
337
+ exports.ZoomEvent.BEFORE_ZOOM = 'zoom.before_zoom';
338
+ exports.ZoomEvent.START = 'zoom.start';
339
+ exports.ZoomEvent.ZOOM = 'zoom';
340
+ exports.ZoomEvent.END = 'zoom.end';
341
+ exports.ZoomEvent = __decorate([
342
+ core.registerUIEvent()
343
+ ], exports.ZoomEvent);
344
+
345
+ exports.KeyEvent = class KeyEvent extends UIEvent {
346
+ };
347
+ exports.KeyEvent.DOWN = 'key.down';
348
+ exports.KeyEvent.HOLD = 'key.hold';
349
+ exports.KeyEvent.UP = 'key.up';
350
+ exports.KeyEvent = __decorate([
351
+ core.registerUIEvent()
352
+ ], exports.KeyEvent);
353
+
354
+ function addInteractionWindow(leafer) {
355
+ if (leafer.isApp)
356
+ return;
357
+ leafer.__eventIds.push(leafer.on_(exports.MoveEvent.BEFORE_MOVE, (e) => {
358
+ const { x, y } = leafer.getValidMove(e.moveX, e.moveY);
359
+ if (x || y)
360
+ leafer.zoomLayer.move(x, y);
361
+ }), leafer.on_(exports.ZoomEvent.BEFORE_ZOOM, (e) => {
362
+ const { zoomLayer } = leafer;
363
+ const changeScale = leafer.getValidScale(e.scale);
364
+ if (changeScale !== 1) {
365
+ core.PointHelper.scaleOf(zoomLayer, e, changeScale);
366
+ zoomLayer.scale = zoomLayer.__.scaleX * changeScale;
367
+ }
368
+ }));
369
+ }
370
+
371
+ function document(leafer) {
372
+ addInteractionWindow(leafer);
373
+ leafer.config.move.scroll = 'limit';
374
+ leafer.config.zoom.min = 1;
375
+ }
376
+
377
+ const debug$1 = core.Debug.get('LeaferTypeCreator');
378
+ const LeaferTypeCreator = {
379
+ list: {},
380
+ register(name, fn) {
381
+ if (list[name]) {
382
+ debug$1.repeat(name);
383
+ }
384
+ else {
385
+ list[name] = fn;
386
+ }
387
+ },
388
+ run(name, leafer) {
389
+ const fn = list[name];
390
+ if (fn) {
391
+ fn(leafer);
392
+ }
393
+ else {
394
+ debug$1.error('no', name);
395
+ }
396
+ }
397
+ };
398
+ const { list, register } = LeaferTypeCreator;
399
+ register('draw', () => { });
400
+ register('design', addInteractionWindow);
401
+ register('document', document);
402
+
403
+ draw.Leafer.prototype.initType = function (type) {
404
+ LeaferTypeCreator.run(type, this);
405
+ };
406
+ draw.Leafer.prototype.getValidMove = function (moveX, moveY) {
407
+ const { scroll, disabled } = this.app.config.move;
408
+ if (scroll) {
409
+ if (Math.abs(moveX) > Math.abs(moveY))
410
+ moveY = 0;
411
+ else
412
+ moveX = 0;
413
+ if (scroll === 'limit') {
414
+ const { x, y, width, height } = new core.Bounds(this.__world).addPoint(this.zoomLayer);
415
+ const right = x + width - this.width, bottom = y + height - this.height;
416
+ if (x >= 0 && right <= 0)
417
+ moveX = 0;
418
+ else if (moveX > 0) {
419
+ if (x + moveX > 0)
420
+ moveX = -x;
421
+ }
422
+ else if (moveX < 0 && right + moveX < 0)
423
+ moveX = -right;
424
+ if (y >= 0 && bottom <= 0)
425
+ moveY = 0;
426
+ else if (moveY > 0) {
427
+ if (y + moveY > 0)
428
+ moveY = -y;
429
+ }
430
+ else if (moveY < 0 && bottom + moveY < 0)
431
+ moveY = -bottom;
432
+ }
433
+ }
434
+ return { x: disabled ? 0 : moveX, y: disabled ? 0 : moveY };
435
+ };
436
+ draw.Leafer.prototype.getValidScale = function (changeScale) {
437
+ const { scaleX } = this.zoomLayer.__, { min, max, disabled } = this.app.config.zoom, absScale = Math.abs(scaleX * changeScale);
438
+ if (absScale < min)
439
+ changeScale = min / scaleX;
440
+ else if (absScale > max)
441
+ changeScale = max / scaleX;
442
+ return disabled ? 1 : changeScale;
443
+ };
444
+
445
+ class Transformer {
446
+ constructor(interaction) {
447
+ this.interaction = interaction;
448
+ }
449
+ move(data) {
450
+ const { interaction } = this;
451
+ if (!this.moveData) {
452
+ const { path } = interaction.selector.getByPoint(data, interaction.hitRadius);
453
+ data.path = path;
454
+ this.moveData = Object.assign(Object.assign({}, data), { moveX: 0, moveY: 0 });
455
+ interaction.cancelHover();
456
+ interaction.emit(exports.MoveEvent.START, this.moveData);
457
+ }
458
+ data.path = this.moveData.path;
459
+ interaction.emit(exports.MoveEvent.BEFORE_MOVE, data);
460
+ interaction.emit(exports.MoveEvent.MOVE, data);
461
+ this.transformEndWait();
462
+ }
463
+ zoom(data) {
464
+ const { interaction } = this;
465
+ if (!this.zoomData) {
466
+ const { path } = interaction.selector.getByPoint(data, interaction.hitRadius);
467
+ data.path = path;
468
+ this.zoomData = Object.assign(Object.assign({}, data), { scale: 1 });
469
+ interaction.cancelHover();
470
+ interaction.emit(exports.ZoomEvent.START, this.zoomData);
471
+ }
472
+ data.path = this.zoomData.path;
473
+ interaction.emit(exports.ZoomEvent.BEFORE_ZOOM, data);
474
+ interaction.emit(exports.ZoomEvent.ZOOM, data);
475
+ this.transformEndWait();
476
+ }
477
+ rotate(data) {
478
+ const { interaction } = this;
479
+ if (!this.rotateData) {
480
+ const { path } = interaction.selector.getByPoint(data, interaction.hitRadius);
481
+ data.path = path;
482
+ this.rotateData = Object.assign(Object.assign({}, data), { rotation: 0 });
483
+ interaction.cancelHover();
484
+ interaction.emit(exports.RotateEvent.START, this.rotateData);
485
+ }
486
+ data.path = this.rotateData.path;
487
+ interaction.emit(exports.RotateEvent.BEFORE_ROTATE, data);
488
+ interaction.emit(exports.RotateEvent.ROTATE, data);
489
+ this.transformEndWait();
490
+ }
491
+ transformEndWait() {
492
+ clearTimeout(this.transformTimer);
493
+ this.transformTimer = setTimeout(() => {
494
+ this.transformEnd();
495
+ }, this.interaction.config.pointer.transformTime);
496
+ }
497
+ transformEnd() {
498
+ this.moveEnd();
499
+ this.zoomEnd();
500
+ this.rotateEnd();
501
+ }
502
+ moveEnd() {
503
+ if (this.moveData) {
504
+ this.interaction.emit(exports.MoveEvent.END, this.moveData);
505
+ this.moveData = null;
506
+ }
507
+ }
508
+ zoomEnd() {
509
+ if (this.zoomData) {
510
+ this.interaction.emit(exports.ZoomEvent.END, this.zoomData);
511
+ this.zoomData = null;
512
+ }
513
+ }
514
+ rotateEnd() {
515
+ if (this.rotateData) {
516
+ this.interaction.emit(exports.RotateEvent.END, this.rotateData);
517
+ this.rotateData = null;
518
+ }
519
+ }
520
+ destroy() {
521
+ this.zoomData = this.moveData = this.rotateData = null;
522
+ }
523
+ }
524
+
525
+ const InteractionHelper = {
526
+ getMoveEventData(center, move, event) {
527
+ return Object.assign(Object.assign({}, event), { x: center.x, y: center.y, moveX: move.x, moveY: move.y });
528
+ },
529
+ getRotateEventData(center, angle, event) {
530
+ return Object.assign(Object.assign({}, event), { x: center.x, y: center.y, rotation: angle });
531
+ },
532
+ getZoomEventData(center, scale, event) {
533
+ return Object.assign(Object.assign({}, event), { x: center.x, y: center.y, scale });
534
+ },
535
+ getDragEventData(startPoint, lastPoint, event) {
536
+ return Object.assign(Object.assign({}, event), { x: event.x, y: event.y, moveX: event.x - lastPoint.x, moveY: event.y - lastPoint.y, totalX: event.x - startPoint.x, totalY: event.y - startPoint.y });
537
+ },
538
+ getDropEventData(event, list, data) {
539
+ return Object.assign(Object.assign({}, event), { list,
540
+ data });
541
+ },
542
+ getSwipeDirection(angle) {
543
+ if (angle < -45 && angle > -135) {
544
+ return exports.SwipeEvent.UP;
545
+ }
546
+ else if (angle > 45 && angle < 135) {
547
+ return exports.SwipeEvent.DOWN;
548
+ }
549
+ else if (angle <= 45 && angle >= -45) {
550
+ return exports.SwipeEvent.RIGHT;
551
+ }
552
+ else {
553
+ return exports.SwipeEvent.LEFT;
554
+ }
555
+ },
556
+ getSwipeEventData(startPoint, lastDragData, event) {
557
+ return Object.assign(Object.assign({}, event), { moveX: lastDragData.moveX, moveY: lastDragData.moveY, totalX: event.x - startPoint.x, totalY: event.y - startPoint.y, type: I.getSwipeDirection(core.PointHelper.getAngle(startPoint, event)) });
558
+ },
559
+ getBase(e) {
560
+ const pointerUpButtons = e.button === 1 ? 4 : e.button;
561
+ return {
562
+ altKey: e.altKey,
563
+ ctrlKey: e.ctrlKey,
564
+ shiftKey: e.shiftKey,
565
+ metaKey: e.metaKey,
566
+ buttons: e.buttons === undefined ? 1 : (e.buttons === 0 ? pointerUpButtons : e.buttons),
567
+ origin: e
568
+ };
569
+ },
570
+ pathHasEventType(path, type) {
571
+ const { list } = path;
572
+ for (let i = 0, len = list.length; i < len; i++) {
573
+ if (list[i].hasEvent(type))
574
+ return true;
575
+ }
576
+ return false;
577
+ },
578
+ filterPathByEventType(path, type) {
579
+ const find = new core.LeafList();
580
+ const { list } = path;
581
+ for (let i = 0, len = list.length; i < len; i++) {
582
+ if (list[i].hasEvent(type))
583
+ find.add(list[i]);
584
+ }
585
+ return find;
586
+ }
587
+ };
588
+ const I = InteractionHelper;
589
+
590
+ const emptyList = new core.LeafList();
591
+ const { getDragEventData, getDropEventData, getSwipeEventData } = InteractionHelper;
592
+ class Dragger {
593
+ constructor(interaction) {
594
+ this.interaction = interaction;
595
+ }
596
+ setDragData(data) {
597
+ if (this.animateWait)
598
+ this.dragEndReal();
599
+ this.downData = this.interaction.downData;
600
+ this.dragData = getDragEventData(data, data, data);
601
+ this.canAnimate = this.canDragOut = true;
602
+ }
603
+ getList() {
604
+ const { proxy } = this.interaction.selector;
605
+ return this.dragging && (!proxy || !proxy.list.length) ? (exports.DragEvent.list || this.dragableList || emptyList) : emptyList;
606
+ }
607
+ checkDrag(data, canDrag) {
608
+ const { interaction } = this;
609
+ if (this.moving && data.buttons < 1) {
610
+ this.canAnimate = false;
611
+ interaction.pointerCancel();
612
+ return;
613
+ }
614
+ if (!this.moving && canDrag) {
615
+ if (this.moving = interaction.canMove(this.downData) || interaction.isHoldRightKey || interaction.isMobileDragEmpty)
616
+ interaction.emit(exports.MoveEvent.START, this.dragData);
617
+ }
618
+ if (!this.moving) {
619
+ this.dragStart(data, canDrag);
620
+ }
621
+ this.drag(data);
622
+ }
623
+ dragStart(data, canDrag) {
624
+ if (!this.dragging) {
625
+ this.dragging = canDrag && PointerButton.left(data);
626
+ if (this.dragging) {
627
+ this.interaction.emit(exports.DragEvent.START, this.dragData);
628
+ this.getDragableList(this.dragData.path);
629
+ }
630
+ }
631
+ }
632
+ getDragableList(path) {
633
+ let leaf;
634
+ for (let i = 0, len = path.length; i < len; i++) {
635
+ leaf = path.list[i];
636
+ if ((leaf.__.draggable || leaf.__.editable) && leaf.__.hitSelf && !leaf.__.locked) {
637
+ this.dragableList = new core.LeafList(leaf);
638
+ break;
639
+ }
640
+ }
641
+ }
642
+ drag(data) {
643
+ const { interaction, dragData, downData } = this;
644
+ const { path, throughPath } = downData;
645
+ this.dragData = getDragEventData(downData, dragData, data);
646
+ if (throughPath)
647
+ this.dragData.throughPath = throughPath;
648
+ this.dragData.path = path;
649
+ if (this.moving) {
650
+ interaction.emit(exports.MoveEvent.BEFORE_MOVE, this.dragData);
651
+ interaction.emit(exports.MoveEvent.MOVE, this.dragData);
652
+ }
653
+ else if (this.dragging) {
654
+ this.dragReal();
655
+ interaction.emit(exports.DragEvent.BEFORE_DRAG, this.dragData);
656
+ interaction.emit(exports.DragEvent.DRAG, this.dragData);
657
+ }
658
+ }
659
+ dragReal() {
660
+ const { running } = this.interaction;
661
+ const list = this.getList();
662
+ if (list.length && running) {
663
+ const { moveX, moveY } = this.dragData;
664
+ list.forEach(leaf => leaf.draggable && leaf.moveWorld(moveX, moveY));
665
+ }
666
+ }
667
+ dragOverOrOut(data) {
668
+ const { interaction } = this;
669
+ const { dragOverPath } = this;
670
+ const { path } = data;
671
+ this.dragOverPath = path;
672
+ if (dragOverPath) {
673
+ if (path.indexAt(0) !== dragOverPath.indexAt(0)) {
674
+ interaction.emit(exports.DragEvent.OUT, data, dragOverPath);
675
+ interaction.emit(exports.DragEvent.OVER, data, path);
676
+ }
677
+ }
678
+ else {
679
+ interaction.emit(exports.DragEvent.OVER, data, path);
680
+ }
681
+ }
682
+ dragEnterOrLeave(data) {
683
+ const { interaction } = this;
684
+ const { dragEnterPath } = this;
685
+ const { path } = data;
686
+ interaction.emit(exports.DragEvent.LEAVE, data, dragEnterPath, path);
687
+ interaction.emit(exports.DragEvent.ENTER, data, path, dragEnterPath);
688
+ this.dragEnterPath = path;
689
+ }
690
+ dragEnd(data, speed) {
691
+ if (!this.dragging && !this.moving)
692
+ return;
693
+ const { moveX, moveY } = this.dragData;
694
+ if (this.interaction.config.move.dragAnimate && this.canAnimate && this.moving && (Math.abs(moveX) > 1 || Math.abs(moveY) > 1)) {
695
+ data = Object.assign({}, data);
696
+ speed = (speed || (data.pointerType === 'touch' ? 2 : 1)) * 0.9;
697
+ core.PointHelper.move(data, moveX * speed, moveY * speed);
698
+ this.drag(data);
699
+ this.animate(() => { this.dragEnd(data, 1); });
700
+ }
701
+ else {
702
+ this.dragEndReal(data);
703
+ }
704
+ }
705
+ dragEndReal(data) {
706
+ const { interaction, downData, dragData } = this;
707
+ if (!data)
708
+ data = dragData;
709
+ const { path, throughPath } = downData;
710
+ const endDragData = getDragEventData(downData, data, data);
711
+ if (throughPath)
712
+ endDragData.throughPath = throughPath;
713
+ endDragData.path = path;
714
+ if (this.moving) {
715
+ this.moving = false;
716
+ interaction.emit(exports.MoveEvent.END, endDragData);
717
+ }
718
+ if (this.dragging) {
719
+ const dropList = this.getList();
720
+ this.dragging = false;
721
+ interaction.emit(exports.DragEvent.END, endDragData);
722
+ this.swipe(data, downData, dragData, endDragData);
723
+ this.drop(data, dropList, this.dragEnterPath);
724
+ }
725
+ this.autoMoveCancel();
726
+ this.dragReset();
727
+ this.animate(null, 'off');
728
+ }
729
+ animate(func, off) {
730
+ const animateWait = func || this.animateWait;
731
+ if (animateWait)
732
+ this.interaction.target.nextRender(animateWait, null, off);
733
+ this.animateWait = func;
734
+ }
735
+ swipe(data, downData, dragData, endDragData) {
736
+ const { interaction } = this;
737
+ if (core.PointHelper.getDistance(downData, data) > interaction.config.pointer.swipeDistance) {
738
+ const swipeData = getSwipeEventData(downData, dragData, endDragData);
739
+ this.interaction.emit(swipeData.type, swipeData);
740
+ }
741
+ }
742
+ drop(data, dropList, dragEnterPath) {
743
+ const dropData = getDropEventData(data, dropList, exports.DragEvent.data);
744
+ dropData.path = dragEnterPath;
745
+ this.interaction.emit(exports.DropEvent.DROP, dropData);
746
+ this.interaction.emit(exports.DragEvent.LEAVE, data, dragEnterPath);
747
+ }
748
+ dragReset() {
749
+ exports.DragEvent.list = exports.DragEvent.data = this.dragableList = this.dragData = this.downData = this.dragOverPath = this.dragEnterPath = null;
750
+ }
751
+ checkDragOut(data) {
752
+ const { interaction } = this;
753
+ this.autoMoveCancel();
754
+ if (this.dragging && !interaction.shrinkCanvasBounds.hitPoint(data))
755
+ this.autoMoveOnDragOut(data);
756
+ }
757
+ autoMoveOnDragOut(data) {
758
+ const { interaction, downData, canDragOut } = this;
759
+ const { autoDistance, dragOut } = interaction.config.move;
760
+ if (!dragOut || !canDragOut || !autoDistance)
761
+ return;
762
+ const bounds = interaction.shrinkCanvasBounds;
763
+ const { x, y } = bounds;
764
+ const right = core.BoundsHelper.maxX(bounds);
765
+ const bottom = core.BoundsHelper.maxY(bounds);
766
+ const moveX = data.x < x ? autoDistance : (right < data.x ? -autoDistance : 0);
767
+ const moveY = data.y < y ? autoDistance : (bottom < data.y ? -autoDistance : 0);
768
+ let totalX = 0, totalY = 0;
769
+ this.autoMoveTimer = setInterval(() => {
770
+ totalX += moveX;
771
+ totalY += moveY;
772
+ core.PointHelper.move(downData, moveX, moveY);
773
+ core.PointHelper.move(this.dragData, moveX, moveY);
774
+ interaction.move(Object.assign(Object.assign({}, data), { moveX, moveY, totalX, totalY }));
775
+ interaction.pointerMoveReal(data);
776
+ }, 10);
777
+ }
778
+ autoMoveCancel() {
779
+ if (this.autoMoveTimer) {
780
+ clearInterval(this.autoMoveTimer);
781
+ this.autoMoveTimer = 0;
782
+ }
783
+ }
784
+ destroy() {
785
+ this.dragReset();
786
+ }
787
+ }
788
+
789
+ const debug = core.Debug.get('emit');
790
+ function emit(type, data, path, excludePath) {
791
+ if (!path && !data.path)
792
+ return;
793
+ let leaf;
794
+ data.type = type;
795
+ if (path) {
796
+ data = Object.assign(Object.assign({}, data), { path });
797
+ }
798
+ else {
799
+ path = data.path;
800
+ }
801
+ data.target = path.indexAt(0);
802
+ try {
803
+ for (let i = path.length - 1; i > -1; i--) {
804
+ leaf = path.list[i];
805
+ if (emitEvent(leaf, type, data, true, excludePath))
806
+ return;
807
+ if (leaf.isApp)
808
+ emitAppChildren(leaf, type, data, true, excludePath);
809
+ }
810
+ for (let i = 0, len = path.length; i < len; i++) {
811
+ leaf = path.list[i];
812
+ if (leaf.isApp)
813
+ emitAppChildren(leaf, type, data, false, excludePath);
814
+ if (emitEvent(leaf, type, data, false, excludePath))
815
+ return;
816
+ }
817
+ }
818
+ catch (e) {
819
+ debug.error(e);
820
+ }
821
+ }
822
+ const allowTypes = ['move', 'zoom', 'rotate', 'key'];
823
+ function emitAppChildren(leaf, type, data, capture, excludePath) {
824
+ if (allowTypes.some(name => type.startsWith(name)) && leaf.__.hitChildren && !exclude(leaf, excludePath)) {
825
+ let child;
826
+ for (let i = 0, len = leaf.children.length; i < len; i++) {
827
+ child = leaf.children[i];
828
+ if (!data.path.has(child) && child.__.hittable)
829
+ emitEvent(child, type, data, capture, excludePath);
830
+ }
831
+ }
832
+ }
833
+ function emitEvent(leaf, type, data, capture, excludePath) {
834
+ if (leaf.destroyed)
835
+ return true;
836
+ if (leaf.__.hitSelf && !exclude(leaf, excludePath)) {
837
+ if (draw.State.updateEventStyle)
838
+ draw.State.updateEventStyle(leaf, type);
839
+ if (leaf.hasEvent(type, capture)) {
840
+ data.phase = capture ? 1 : ((leaf === data.target) ? 2 : 3);
841
+ const event = core.EventCreator.get(type, data);
842
+ leaf.emitEvent(event, capture);
843
+ if (event.isStop)
844
+ return true;
845
+ }
846
+ }
847
+ return false;
848
+ }
849
+ function exclude(leaf, excludePath) {
850
+ return excludePath && excludePath.has(leaf);
851
+ }
852
+
853
+ const MultiTouchHelper = {
854
+ getData(list) {
855
+ const a = list[0];
856
+ const b = list[1];
857
+ const lastCenter = core.PointHelper.getCenter(a.from, b.from);
858
+ const center = core.PointHelper.getCenter(a.to, b.to);
859
+ const move = { x: center.x - lastCenter.x, y: center.y - lastCenter.y };
860
+ const lastDistance = core.PointHelper.getDistance(a.from, b.from);
861
+ const distance = core.PointHelper.getDistance(a.to, b.to);
862
+ const scale = distance / lastDistance;
863
+ const angle = core.PointHelper.getRotation(a.from, b.from, a.to, b.to);
864
+ return { move, scale, angle, center };
865
+ }
866
+ };
867
+
868
+ const config = {
869
+ wheel: {
870
+ zoomSpeed: 0.5,
871
+ moveSpeed: 0.5,
872
+ rotateSpeed: 0.5,
873
+ delta: { x: 80 / 4, y: 8.0 },
874
+ preventDefault: true
875
+ },
876
+ pointer: {
877
+ hitRadius: 5,
878
+ tapTime: 120,
879
+ longPressTime: 800,
880
+ transformTime: 500,
881
+ hover: true,
882
+ dragHover: true,
883
+ dragDistance: 2,
884
+ swipeDistance: 20,
885
+ preventDefaultMenu: true
886
+ },
887
+ cursor: {}
888
+ };
889
+
890
+ const { pathHasEventType, getMoveEventData, getZoomEventData, getRotateEventData } = InteractionHelper;
891
+ class InteractionBase {
892
+ get dragging() { return this.dragger.dragging; }
893
+ get moveMode() { return this.config.move.drag || this.isHoldSpaceKey || this.isHoldMiddleKey || (this.isHoldRightKey && this.dragger.moving) || this.isDragEmpty; }
894
+ get isDragEmpty() { return this.config.move.dragEmpty && this.isRootPath(this.hoverData) && (!this.downData || this.isRootPath(this.downData)); }
895
+ get isMobileDragEmpty() { return this.config.move.dragEmpty && !this.config.pointer.hover && this.downData && this.isTreePath(this.downData); }
896
+ get isHoldMiddleKey() { return this.config.move.holdMiddleKey && this.downData && PointerButton.middle(this.downData); }
897
+ get isHoldRightKey() { return this.config.move.holdRightKey && this.downData && PointerButton.right(this.downData); }
898
+ get isHoldSpaceKey() { return this.config.move.holdSpaceKey && Keyboard.isHoldSpaceKey(); }
899
+ get hitRadius() { return this.config.pointer.hitRadius; }
900
+ constructor(target, canvas, selector, userConfig) {
901
+ this.config = config;
902
+ this.tapCount = 0;
903
+ this.downKeyMap = {};
904
+ this.target = target;
905
+ this.canvas = canvas;
906
+ this.selector = selector;
907
+ this.defaultPath = new core.LeafList(target);
908
+ this.transformer = new Transformer(this);
909
+ this.dragger = new Dragger(this);
910
+ if (userConfig)
911
+ this.config = core.DataHelper.default(userConfig, this.config);
912
+ this.__listenEvents();
913
+ }
914
+ start() {
915
+ this.running = true;
916
+ }
917
+ stop() {
918
+ this.running = false;
919
+ }
920
+ receive(_event) { }
921
+ pointerDown(data, useDefaultPath) {
922
+ if (!data)
923
+ data = this.hoverData;
924
+ if (!data)
925
+ return;
926
+ PointerButton.defaultLeft(data);
927
+ this.updateDownData(data);
928
+ this.checkPath(data, useDefaultPath);
929
+ this.downTime = Date.now();
930
+ this.emit(exports.PointerEvent.BEFORE_DOWN, data);
931
+ this.emit(exports.PointerEvent.DOWN, data);
932
+ if (PointerButton.left(data)) {
933
+ this.tapWait();
934
+ this.longPressWait(data);
935
+ }
936
+ else if (PointerButton.right(data)) {
937
+ this.waitMenuTap = true;
938
+ }
939
+ this.dragger.setDragData(data);
940
+ if (!this.isHoldRightKey)
941
+ this.updateCursor(data);
942
+ }
943
+ pointerMove(data) {
944
+ if (!data)
945
+ data = this.hoverData;
946
+ if (!data)
947
+ return;
948
+ const { downData } = this;
949
+ if (downData)
950
+ PointerButton.defaultLeft(data);
951
+ const hit = this.canvas.bounds.hitPoint(data);
952
+ if (hit || downData) {
953
+ this.pointerMoveReal(data);
954
+ if (downData)
955
+ this.dragger.checkDragOut(data);
956
+ }
957
+ }
958
+ pointerMoveReal(data) {
959
+ const { dragHover, dragDistance } = this.config.pointer;
960
+ this.emit(exports.PointerEvent.BEFORE_MOVE, data, this.defaultPath);
961
+ if (this.downData) {
962
+ const canDrag = core.PointHelper.getDistance(this.downData, data) > dragDistance;
963
+ if (canDrag) {
964
+ if (this.waitTap)
965
+ this.pointerWaitCancel();
966
+ this.waitMenuTap = false;
967
+ }
968
+ this.dragger.checkDrag(data, canDrag);
969
+ }
970
+ if (!this.dragger.moving) {
971
+ this.updateHoverData(data);
972
+ this.checkPath(data);
973
+ this.emit(exports.PointerEvent.MOVE, data);
974
+ if (!(this.dragging && !dragHover))
975
+ this.pointerHover(data);
976
+ if (this.dragger.dragging) {
977
+ this.dragger.dragOverOrOut(data);
978
+ this.dragger.dragEnterOrLeave(data);
979
+ }
980
+ }
981
+ this.updateCursor(this.downData || data);
982
+ }
983
+ pointerUp(data) {
984
+ const { downData } = this;
985
+ if (!data)
986
+ data = downData;
987
+ if (!downData)
988
+ return;
989
+ PointerButton.defaultLeft(data);
990
+ this.findPath(data);
991
+ const upData = Object.assign(Object.assign({}, data), { path: data.path.clone() });
992
+ data.path.addList(downData.path.list);
993
+ this.checkPath(data);
994
+ this.downData = null;
995
+ this.emit(exports.PointerEvent.BEFORE_UP, data);
996
+ this.emit(exports.PointerEvent.UP, data);
997
+ this.touchLeave(data);
998
+ if (!data.isCancel) {
999
+ this.tap(data);
1000
+ this.menuTap(data);
1001
+ }
1002
+ this.dragger.dragEnd(data);
1003
+ this.updateCursor(upData);
1004
+ }
1005
+ pointerCancel() {
1006
+ const data = Object.assign({}, this.dragger.dragData);
1007
+ data.isCancel = true;
1008
+ this.pointerUp(data);
1009
+ }
1010
+ multiTouch(data, list) {
1011
+ const { move, angle, scale, center } = MultiTouchHelper.getData(list);
1012
+ this.rotate(getRotateEventData(center, angle, data));
1013
+ this.zoom(getZoomEventData(center, scale, data));
1014
+ this.move(getMoveEventData(center, move, data));
1015
+ }
1016
+ menu(data) {
1017
+ this.findPath(data);
1018
+ this.emit(exports.PointerEvent.MENU, data);
1019
+ }
1020
+ menuTap(data) {
1021
+ if (this.waitMenuTap)
1022
+ this.emit(exports.PointerEvent.MENU_TAP, data);
1023
+ }
1024
+ move(data) {
1025
+ this.transformer.move(data);
1026
+ }
1027
+ zoom(data) {
1028
+ this.transformer.zoom(data);
1029
+ }
1030
+ rotate(data) {
1031
+ this.transformer.rotate(data);
1032
+ }
1033
+ transformEnd() {
1034
+ this.transformer.transformEnd();
1035
+ }
1036
+ keyDown(data) {
1037
+ const { code } = data;
1038
+ if (!this.downKeyMap[code]) {
1039
+ this.downKeyMap[code] = true;
1040
+ Keyboard.setDownCode(code);
1041
+ this.emit(exports.KeyEvent.HOLD, data, this.defaultPath);
1042
+ if (this.moveMode) {
1043
+ this.cancelHover();
1044
+ this.updateCursor();
1045
+ }
1046
+ }
1047
+ this.emit(exports.KeyEvent.DOWN, data, this.defaultPath);
1048
+ }
1049
+ keyUp(data) {
1050
+ const { code } = data;
1051
+ this.downKeyMap[code] = false;
1052
+ Keyboard.setUpCode(code);
1053
+ this.emit(exports.KeyEvent.UP, data, this.defaultPath);
1054
+ if (this.cursor === 'grab')
1055
+ this.updateCursor();
1056
+ }
1057
+ pointerHover(data) {
1058
+ if (this.config.pointer.hover) {
1059
+ this.pointerOverOrOut(data);
1060
+ this.pointerEnterOrLeave(data);
1061
+ }
1062
+ }
1063
+ pointerOverOrOut(data) {
1064
+ const { path } = data;
1065
+ const { overPath } = this;
1066
+ this.overPath = path;
1067
+ if (overPath) {
1068
+ if (path.indexAt(0) !== overPath.indexAt(0)) {
1069
+ this.emit(exports.PointerEvent.OUT, data, overPath);
1070
+ this.emit(exports.PointerEvent.OVER, data, path);
1071
+ }
1072
+ }
1073
+ else {
1074
+ this.emit(exports.PointerEvent.OVER, data, path);
1075
+ }
1076
+ }
1077
+ pointerEnterOrLeave(data) {
1078
+ let { path } = data;
1079
+ if (this.downData && !this.moveMode) {
1080
+ path = path.clone();
1081
+ this.downData.path.forEach(leaf => path.add(leaf));
1082
+ }
1083
+ const { enterPath } = this;
1084
+ this.enterPath = path;
1085
+ this.emit(exports.PointerEvent.LEAVE, data, enterPath, path);
1086
+ this.emit(exports.PointerEvent.ENTER, data, path, enterPath);
1087
+ }
1088
+ touchLeave(data) {
1089
+ if (data.pointerType === 'touch') {
1090
+ if (this.enterPath) {
1091
+ this.emit(exports.PointerEvent.LEAVE, data);
1092
+ if (this.dragger.dragging)
1093
+ this.emit(exports.DropEvent.LEAVE, data);
1094
+ }
1095
+ }
1096
+ }
1097
+ tap(data) {
1098
+ const { pointer } = this.config;
1099
+ const longTap = this.longTap(data);
1100
+ if (!pointer.tapMore && longTap)
1101
+ return;
1102
+ if (!this.waitTap)
1103
+ return;
1104
+ if (pointer.tapMore)
1105
+ this.emitTap(data);
1106
+ const useTime = Date.now() - this.downTime;
1107
+ const hasDouble = [exports.PointerEvent.DOUBLE_TAP, exports.PointerEvent.DOUBLE_CLICK].some(type => pathHasEventType(data.path, type));
1108
+ if (useTime < pointer.tapTime + 50 && hasDouble) {
1109
+ this.tapCount++;
1110
+ if (this.tapCount === 2) {
1111
+ this.tapWaitCancel();
1112
+ this.emitDoubleTap(data);
1113
+ }
1114
+ else {
1115
+ clearTimeout(this.tapTimer);
1116
+ this.tapTimer = setTimeout(() => {
1117
+ if (!pointer.tapMore) {
1118
+ this.tapWaitCancel();
1119
+ this.emitTap(data);
1120
+ }
1121
+ }, pointer.tapTime);
1122
+ }
1123
+ }
1124
+ else {
1125
+ if (!pointer.tapMore) {
1126
+ this.tapWaitCancel();
1127
+ this.emitTap(data);
1128
+ }
1129
+ }
1130
+ }
1131
+ findPath(data, options) {
1132
+ const { hitRadius, through } = this.config.pointer;
1133
+ const find = this.selector.getByPoint(data, hitRadius, options || { through });
1134
+ if (find.throughPath)
1135
+ data.throughPath = find.throughPath;
1136
+ data.path = find.path;
1137
+ return find.path;
1138
+ }
1139
+ isRootPath(data) {
1140
+ return data && data.path.list[0].isLeafer;
1141
+ }
1142
+ isTreePath(data) {
1143
+ const app = this.target.app;
1144
+ if (!app || !app.isApp)
1145
+ return false;
1146
+ return app.editor && (!data.path.has(app.editor) && data.path.has(app.tree));
1147
+ }
1148
+ checkPath(data, useDefaultPath) {
1149
+ if (useDefaultPath || this.canMove(data))
1150
+ data.path = this.defaultPath;
1151
+ }
1152
+ canMove(data) {
1153
+ return this.moveMode && data && data.path.list.every(item => !item.isOutside);
1154
+ }
1155
+ isDrag(leaf) {
1156
+ return this.dragger.getList().has(leaf);
1157
+ }
1158
+ isPress(leaf) {
1159
+ return this.downData && this.downData.path.has(leaf);
1160
+ }
1161
+ isHover(leaf) {
1162
+ return this.enterPath && this.enterPath.has(leaf);
1163
+ }
1164
+ isFocus(leaf) {
1165
+ return this.focusData === leaf;
1166
+ }
1167
+ cancelHover() {
1168
+ const { hoverData } = this;
1169
+ if (hoverData) {
1170
+ hoverData.path = this.defaultPath;
1171
+ this.pointerHover(hoverData);
1172
+ }
1173
+ }
1174
+ updateDownData(data, options, merge) {
1175
+ const { downData } = this;
1176
+ if (!data && downData)
1177
+ data = downData;
1178
+ if (!data)
1179
+ return;
1180
+ this.findPath(data, options);
1181
+ if (merge && downData)
1182
+ data.path.addList(downData.path.list);
1183
+ this.downData = data;
1184
+ }
1185
+ updateHoverData(data) {
1186
+ if (!data)
1187
+ data = this.hoverData;
1188
+ if (!data)
1189
+ return;
1190
+ this.findPath(data, { exclude: this.dragger.getList(), name: exports.PointerEvent.MOVE });
1191
+ this.hoverData = data;
1192
+ }
1193
+ updateCursor(data) {
1194
+ if (this.config.cursor.stop || !this.config.pointer.hover)
1195
+ return;
1196
+ if (!data) {
1197
+ this.updateHoverData();
1198
+ data = this.downData || this.hoverData;
1199
+ }
1200
+ if (this.dragger.moving) {
1201
+ return this.setCursor('grabbing');
1202
+ }
1203
+ else if (this.canMove(data)) {
1204
+ return this.setCursor(this.downData ? 'grabbing' : 'grab');
1205
+ }
1206
+ else if (!data)
1207
+ return;
1208
+ let leaf, cursor;
1209
+ const { path } = data;
1210
+ for (let i = 0, len = path.length; i < len; i++) {
1211
+ leaf = path.list[i];
1212
+ cursor = leaf.cursor;
1213
+ if (cursor)
1214
+ break;
1215
+ }
1216
+ this.setCursor(cursor);
1217
+ }
1218
+ setCursor(cursor) {
1219
+ this.cursor = cursor;
1220
+ }
1221
+ emitTap(data) {
1222
+ this.emit(exports.PointerEvent.TAP, data);
1223
+ this.emit(exports.PointerEvent.CLICK, data);
1224
+ }
1225
+ emitDoubleTap(data) {
1226
+ this.emit(exports.PointerEvent.DOUBLE_TAP, data);
1227
+ this.emit(exports.PointerEvent.DOUBLE_CLICK, data);
1228
+ }
1229
+ pointerWaitCancel() {
1230
+ this.tapWaitCancel();
1231
+ this.longPressWaitCancel();
1232
+ }
1233
+ tapWait() {
1234
+ clearTimeout(this.tapTimer);
1235
+ this.waitTap = true;
1236
+ }
1237
+ tapWaitCancel() {
1238
+ clearTimeout(this.tapTimer);
1239
+ this.waitTap = false;
1240
+ this.tapCount = 0;
1241
+ }
1242
+ longPressWait(data) {
1243
+ clearTimeout(this.longPressTimer);
1244
+ this.longPressTimer = setTimeout(() => {
1245
+ this.longPressed = true;
1246
+ this.emit(exports.PointerEvent.LONG_PRESS, data);
1247
+ }, this.config.pointer.longPressTime);
1248
+ }
1249
+ longTap(data) {
1250
+ let longTap;
1251
+ if (this.longPressed) {
1252
+ this.emit(exports.PointerEvent.LONG_TAP, data);
1253
+ if (pathHasEventType(data.path, exports.PointerEvent.LONG_TAP))
1254
+ longTap = true;
1255
+ }
1256
+ this.longPressWaitCancel();
1257
+ return longTap;
1258
+ }
1259
+ longPressWaitCancel() {
1260
+ clearTimeout(this.longPressTimer);
1261
+ this.longPressed = false;
1262
+ }
1263
+ __onResize() {
1264
+ this.shrinkCanvasBounds = new core.Bounds(this.canvas.bounds);
1265
+ this.shrinkCanvasBounds.spread(-2);
1266
+ }
1267
+ __listenEvents() {
1268
+ const { target } = this;
1269
+ this.__eventIds = [target.on_(core.ResizeEvent.RESIZE, this.__onResize, this)];
1270
+ target.once(core.LeaferEvent.READY, () => this.__onResize());
1271
+ }
1272
+ __removeListenEvents() {
1273
+ this.target.off_(this.__eventIds);
1274
+ this.__eventIds.length = 0;
1275
+ }
1276
+ emit(type, data, path, excludePath) {
1277
+ if (this.running)
1278
+ emit(type, data, path, excludePath);
1279
+ }
1280
+ destroy() {
1281
+ if (this.__eventIds.length) {
1282
+ this.stop();
1283
+ this.__removeListenEvents();
1284
+ this.dragger.destroy();
1285
+ this.transformer.destroy();
1286
+ this.downData = this.overPath = this.enterPath = null;
1287
+ }
1288
+ }
1289
+ }
1290
+
1291
+ class Cursor {
1292
+ static set(name, value) {
1293
+ this.custom[name] = value;
1294
+ }
1295
+ static get(name) {
1296
+ return this.custom[name];
1297
+ }
1298
+ }
1299
+ Cursor.custom = {};
1300
+
1301
+ class HitCanvasManager extends core.CanvasManager {
1302
+ constructor() {
1303
+ super(...arguments);
1304
+ this.maxTotal = 1000;
1305
+ this.pathList = new core.LeafList();
1306
+ this.pixelList = new core.LeafList();
1307
+ }
1308
+ getPixelType(leaf, config) {
1309
+ this.__autoClear();
1310
+ this.pixelList.add(leaf);
1311
+ return core.Creator.hitCanvas(config);
1312
+ }
1313
+ getPathType(leaf) {
1314
+ this.__autoClear();
1315
+ this.pathList.add(leaf);
1316
+ return core.Creator.hitCanvas();
1317
+ }
1318
+ clearImageType() {
1319
+ this.__clearLeafList(this.pixelList);
1320
+ }
1321
+ clearPathType() {
1322
+ this.__clearLeafList(this.pathList);
1323
+ }
1324
+ __clearLeafList(leafList) {
1325
+ if (leafList.length) {
1326
+ leafList.forEach(leaf => {
1327
+ if (leaf.__hitCanvas) {
1328
+ leaf.__hitCanvas.destroy();
1329
+ leaf.__hitCanvas = null;
1330
+ }
1331
+ });
1332
+ leafList.reset();
1333
+ }
1334
+ }
1335
+ __autoClear() {
1336
+ if (this.pathList.length + this.pixelList.length > this.maxTotal)
1337
+ this.clear();
1338
+ }
1339
+ clear() {
1340
+ this.clearPathType();
1341
+ this.clearImageType();
1342
+ }
1343
+ }
1344
+
1345
+ const canvas = core.LeaferCanvasBase.prototype;
1346
+ canvas.hitFill = function (point, fillRule) {
1347
+ return fillRule ? this.context.isPointInPath(point.x, point.y, fillRule) : this.context.isPointInPath(point.x, point.y);
1348
+ };
1349
+ canvas.hitStroke = function (point, strokeWidth) {
1350
+ this.strokeWidth = strokeWidth;
1351
+ return this.context.isPointInStroke(point.x, point.y);
1352
+ };
1353
+ canvas.hitPixel = function (radiusPoint, offset, scale = 1) {
1354
+ let { x, y, radiusX, radiusY } = radiusPoint;
1355
+ if (offset)
1356
+ x -= offset.x, y -= offset.y;
1357
+ core.tempBounds.set(x - radiusX, y - radiusY, radiusX * 2, radiusY * 2).scale(scale).ceil();
1358
+ const { data } = this.context.getImageData(core.tempBounds.x, core.tempBounds.y, core.tempBounds.width, core.tempBounds.height);
1359
+ for (let i = 0, len = data.length; i < len; i += 4) {
1360
+ if (data[i + 3] > 0)
1361
+ return true;
1362
+ }
1363
+ return data[3] > 0;
1364
+ };
1365
+
1366
+ const { toInnerRadiusPointOf, copy, setRadius } = core.PointHelper;
1367
+ const inner = {};
1368
+ const leaf = core.Leaf.prototype;
1369
+ leaf.__hitWorld = function (point) {
1370
+ if (this.__.hitRadius) {
1371
+ copy(inner, point), point = inner;
1372
+ setRadius(point, this.__.hitRadius);
1373
+ }
1374
+ toInnerRadiusPointOf(point, this.__world, inner);
1375
+ const { width, height } = this.__world;
1376
+ const isSmall = width < 10 && height < 10;
1377
+ if (this.__.hitBox || isSmall) {
1378
+ if (core.BoundsHelper.hitRadiusPoint(this.__layout.boxBounds, inner))
1379
+ return true;
1380
+ if (isSmall)
1381
+ return false;
1382
+ }
1383
+ if (this.__layout.hitCanvasChanged || !this.__hitCanvas) {
1384
+ this.__updateHitCanvas();
1385
+ if (!this.__layout.boundsChanged)
1386
+ this.__layout.hitCanvasChanged = false;
1387
+ }
1388
+ return this.__hit(inner);
1389
+ };
1390
+ leaf.__hitFill = function (inner) { var _a; return (_a = this.__hitCanvas) === null || _a === void 0 ? void 0 : _a.hitFill(inner, this.__.windingRule); };
1391
+ leaf.__hitStroke = function (inner, strokeWidth) { var _a; return (_a = this.__hitCanvas) === null || _a === void 0 ? void 0 : _a.hitStroke(inner, strokeWidth); };
1392
+ leaf.__hitPixel = function (inner) { var _a; return (_a = this.__hitCanvas) === null || _a === void 0 ? void 0 : _a.hitPixel(inner, this.__layout.renderBounds, this.__hitCanvas.hitScale); };
1393
+ leaf.__drawHitPath = function (canvas) { if (canvas)
1394
+ this.__drawRenderPath(canvas); };
1395
+
1396
+ const matrix = new core.Matrix();
1397
+ const ui$1 = draw.UI.prototype;
1398
+ ui$1.__updateHitCanvas = function () {
1399
+ const data = this.__, { hitCanvasManager } = this.leafer;
1400
+ const isHitPixelFill = data.__pixelFill && data.hitFill === 'pixel';
1401
+ const isHitPixelStroke = data.__pixelStroke && data.hitStroke === 'pixel';
1402
+ const isHitPixel = isHitPixelFill || isHitPixelStroke;
1403
+ if (!this.__hitCanvas)
1404
+ this.__hitCanvas = isHitPixel ? hitCanvasManager.getPixelType(this, { contextSettings: { willReadFrequently: true } }) : hitCanvasManager.getPathType(this);
1405
+ const h = this.__hitCanvas;
1406
+ if (isHitPixel) {
1407
+ const { renderBounds } = this.__layout;
1408
+ const size = core.Platform.image.hitCanvasSize;
1409
+ const scale = h.hitScale = core.tempBounds.set(0, 0, size, size).getFitMatrix(renderBounds, 0.5).a;
1410
+ const { x, y, width, height } = core.tempBounds.set(renderBounds).scale(scale);
1411
+ h.resize({ width, height, pixelRatio: 1 });
1412
+ h.clear();
1413
+ draw.ImageManager.patternLocked = true;
1414
+ this.__renderShape(h, { matrix: matrix.setWith(this.__world).scaleWith(1 / scale).invertWith().translate(-x, -y) }, !isHitPixelFill, !isHitPixelStroke);
1415
+ draw.ImageManager.patternLocked = false;
1416
+ h.resetTransform();
1417
+ data.__isHitPixel = true;
1418
+ }
1419
+ else {
1420
+ data.__isHitPixel && (data.__isHitPixel = false);
1421
+ }
1422
+ this.__drawHitPath(h);
1423
+ h.setStrokeOptions(data);
1424
+ };
1425
+ ui$1.__hit = function (inner) {
1426
+ if (core.Platform.name === 'miniapp')
1427
+ this.__drawHitPath(this.__hitCanvas);
1428
+ const data = this.__;
1429
+ if (data.__isHitPixel && this.__hitPixel(inner))
1430
+ return true;
1431
+ const { hitFill } = data;
1432
+ const needHitFillPath = ((data.fill && hitFill == 'path') || hitFill === 'all');
1433
+ if (needHitFillPath && this.__hitFill(inner))
1434
+ return true;
1435
+ const { hitStroke, __strokeWidth } = data;
1436
+ const needHitStrokePath = ((data.stroke && hitStroke == 'path') || hitStroke === 'all');
1437
+ if (!needHitFillPath && !needHitStrokePath)
1438
+ return false;
1439
+ const radiusWidth = inner.radiusX * 2;
1440
+ let hitWidth = radiusWidth;
1441
+ if (needHitStrokePath) {
1442
+ switch (data.strokeAlign) {
1443
+ case 'inside':
1444
+ hitWidth += __strokeWidth * 2;
1445
+ if (!needHitFillPath && this.__hitFill(inner) && this.__hitStroke(inner, hitWidth))
1446
+ return true;
1447
+ hitWidth = radiusWidth;
1448
+ break;
1449
+ case 'center':
1450
+ hitWidth += __strokeWidth;
1451
+ break;
1452
+ case 'outside':
1453
+ hitWidth += __strokeWidth * 2;
1454
+ if (!needHitFillPath) {
1455
+ if (!this.__hitFill(inner) && this.__hitStroke(inner, hitWidth))
1456
+ return true;
1457
+ hitWidth = radiusWidth;
1458
+ }
1459
+ break;
1460
+ }
1461
+ }
1462
+ return hitWidth ? this.__hitStroke(inner, hitWidth) : false;
1463
+ };
1464
+
1465
+ const ui = new draw.UI();
1466
+ draw.Rect.prototype.__updateHitCanvas = function () {
1467
+ if (this.stroke || this.cornerRadius)
1468
+ ui.__updateHitCanvas.call(this);
1469
+ };
1470
+ draw.Rect.prototype.__hitFill = function (inner) {
1471
+ return this.__hitCanvas ? ui.__hitFill.call(this, inner) : core.BoundsHelper.hitRadiusPoint(this.__layout.boxBounds, inner);
1472
+ };
1473
+
1474
+ draw.UI.prototype.find = function (condition, options) {
1475
+ return this.leafer ? this.leafer.selector.getBy(condition, this, false, options) : [];
1476
+ };
1477
+ draw.UI.prototype.findOne = function (condition, options) {
1478
+ return this.leafer ? this.leafer.selector.getBy(condition, this, true, options) : null;
1479
+ };
1480
+ draw.Group.prototype.pick = function (hitPoint, options) {
1481
+ this.__layout.update();
1482
+ if (!options)
1483
+ options = {};
1484
+ return this.leafer ? this.leafer.selector.getByPoint(hitPoint, options.hitRadius || 0, Object.assign(Object.assign({}, options), { target: this })) : null;
1485
+ };
1486
+
1487
+ exports.Cursor = Cursor;
1488
+ exports.HitCanvasManager = HitCanvasManager;
1489
+ exports.InteractionBase = InteractionBase;
1490
+ exports.InteractionHelper = InteractionHelper;
1491
+ exports.Keyboard = Keyboard;
1492
+ exports.LeaferTypeCreator = LeaferTypeCreator;
1493
+ exports.MultiTouchHelper = MultiTouchHelper;
1494
+ exports.PointerButton = PointerButton;
1495
+ exports.UIEvent = UIEvent;
1496
+ Object.keys(draw).forEach(function (k) {
1497
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
1498
+ enumerable: true,
1499
+ get: function () { return draw[k]; }
1500
+ });
1501
+ });