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

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