@leafer-ui/core 1.0.0-rc.9 → 1.0.0

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