leafer-ui 1.0.0-beta.8 → 1.0.0-rc.10

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.
@@ -0,0 +1,2949 @@
1
+ import { Debug, LeaferCanvasBase, Platform, DataHelper, canvasSizeAttrs, ResizeEvent, canvasPatch, Creator, LeaferImage, FileHelper, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, LeafLevelList, LayoutEvent, Run, ImageManager, AnimateEvent, BoundsHelper, Answer, MatrixHelper, ImageEvent, PointHelper, Direction4, TwoPointBoundsHelper, TaskProcessor, Matrix } from '@leafer/core';
2
+ export * from '@leafer/core';
3
+ export { LeaferImage } from '@leafer/core';
4
+ import { InteractionHelper, Platform as Platform$1, MathHelper, InteractionBase, Cursor, HitCanvasManager } from '@leafer-ui/core';
5
+ export * from '@leafer-ui/core';
6
+ import { ColorConvert, Export, Group, TextConvert, Paint, PaintImage as PaintImage$1, PaintGradient as PaintGradient$1, Effect } from '@leafer-ui/draw';
7
+
8
+ const debug$2 = Debug.get('LeaferCanvas');
9
+ class LeaferCanvas extends LeaferCanvasBase {
10
+ init() {
11
+ const { view } = this.config;
12
+ view ? this.__createViewFrom(view) : this.__createView();
13
+ const { style } = this.view;
14
+ style.display || (style.display = 'block');
15
+ this.parentView = this.view.parentElement;
16
+ if (this.parentView)
17
+ this.parentView.style.userSelect = 'none';
18
+ if (Platform.syncDomFont && !this.parentView) {
19
+ this.view.style.display = 'none';
20
+ document.body.appendChild(this.view);
21
+ }
22
+ this.__createContext();
23
+ if (!this.autoLayout)
24
+ this.resize(this.config);
25
+ }
26
+ set backgroundColor(color) { this.view.style.backgroundColor = color; }
27
+ get backgroundColor() { return this.view.style.backgroundColor; }
28
+ set hittable(hittable) { this.view.style.pointerEvents = hittable ? 'auto' : 'none'; }
29
+ get hittable() { return this.view.style.pointerEvents !== 'none'; }
30
+ __createView() {
31
+ this.view = document.createElement('canvas');
32
+ }
33
+ __createViewFrom(inputView) {
34
+ let find = (typeof inputView === 'string') ? document.getElementById(inputView) : inputView;
35
+ if (find) {
36
+ if (find instanceof HTMLCanvasElement) {
37
+ this.view = find;
38
+ }
39
+ else {
40
+ let parent = find;
41
+ if (find === window || find === document) {
42
+ const div = document.createElement('div');
43
+ const { style } = div;
44
+ style.position = 'absolute';
45
+ style.top = style.bottom = style.left = style.right = '0px';
46
+ document.body.appendChild(div);
47
+ parent = div;
48
+ }
49
+ this.__createView();
50
+ const view = this.view;
51
+ if (parent.hasChildNodes()) {
52
+ const { style } = view;
53
+ style.position = 'absolute';
54
+ style.top = style.left = '0px';
55
+ parent.style.position || (parent.style.position = 'relative');
56
+ }
57
+ parent.appendChild(view);
58
+ }
59
+ }
60
+ else {
61
+ debug$2.error(`no id: ${inputView}`);
62
+ this.__createView();
63
+ }
64
+ }
65
+ updateViewSize() {
66
+ const { width, height, pixelRatio } = this;
67
+ const { style } = this.view;
68
+ style.width = width + 'px';
69
+ style.height = height + 'px';
70
+ this.view.width = Math.ceil(width * pixelRatio);
71
+ this.view.height = Math.ceil(height * pixelRatio);
72
+ }
73
+ updateClientBounds() {
74
+ this.clientBounds = this.view.getBoundingClientRect();
75
+ }
76
+ startAutoLayout(autoBounds, listener) {
77
+ this.autoBounds = autoBounds;
78
+ this.resizeListener = listener;
79
+ try {
80
+ this.resizeObserver = new ResizeObserver((entries) => {
81
+ this.updateClientBounds();
82
+ for (const entry of entries)
83
+ this.checkAutoBounds(entry.contentRect);
84
+ });
85
+ const parent = this.parentView;
86
+ if (parent) {
87
+ this.resizeObserver.observe(parent);
88
+ this.checkAutoBounds(parent.getBoundingClientRect());
89
+ }
90
+ }
91
+ catch (_a) {
92
+ this.imitateResizeObserver();
93
+ }
94
+ }
95
+ imitateResizeObserver() {
96
+ if (this.autoLayout) {
97
+ if (this.parentView)
98
+ this.checkAutoBounds(this.parentView.getBoundingClientRect());
99
+ Platform.requestRender(this.imitateResizeObserver.bind(this));
100
+ }
101
+ }
102
+ checkAutoBounds(parentSize) {
103
+ const view = this.view;
104
+ const { x, y, width, height } = this.autoBounds.getBoundsFrom(parentSize);
105
+ if (width !== this.width || height !== this.height) {
106
+ const { style } = view;
107
+ const { pixelRatio } = this;
108
+ style.marginLeft = x + 'px';
109
+ style.marginTop = y + 'px';
110
+ const size = { width, height, pixelRatio };
111
+ const oldSize = {};
112
+ DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
113
+ this.resize(size);
114
+ if (this.width !== undefined)
115
+ this.resizeListener(new ResizeEvent(size, oldSize));
116
+ }
117
+ }
118
+ stopAutoLayout() {
119
+ this.autoLayout = false;
120
+ this.resizeListener = null;
121
+ if (this.resizeObserver) {
122
+ this.resizeObserver.disconnect();
123
+ this.resizeObserver = null;
124
+ }
125
+ }
126
+ unrealCanvas() {
127
+ if (!this.unreal && this.parentView) {
128
+ const view = this.view;
129
+ if (view)
130
+ view.remove();
131
+ this.view = this.parentView;
132
+ this.unreal = true;
133
+ }
134
+ }
135
+ destroy() {
136
+ if (this.view) {
137
+ this.stopAutoLayout();
138
+ if (!this.unreal) {
139
+ const view = this.view;
140
+ if (view.parentElement)
141
+ view.remove();
142
+ }
143
+ super.destroy();
144
+ }
145
+ }
146
+ }
147
+
148
+ canvasPatch(CanvasRenderingContext2D.prototype);
149
+ canvasPatch(Path2D.prototype);
150
+
151
+ const { mineType, fileType } = FileHelper;
152
+ Object.assign(Creator, {
153
+ canvas: (options, manager) => new LeaferCanvas(options, manager),
154
+ image: (options) => new LeaferImage(options)
155
+ });
156
+ function useCanvas(_canvasType, _power) {
157
+ Platform.origin = {
158
+ createCanvas(width, height) {
159
+ const canvas = document.createElement('canvas');
160
+ canvas.width = width;
161
+ canvas.height = height;
162
+ return canvas;
163
+ },
164
+ canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
165
+ canvasToBolb: (canvas, type, quality) => new Promise((resolve) => canvas.toBlob(resolve, mineType(type), quality)),
166
+ canvasSaveAs: (canvas, filename, quality) => {
167
+ return new Promise((resolve) => {
168
+ let el = document.createElement('a');
169
+ el.href = canvas.toDataURL(mineType(fileType(filename)), quality);
170
+ el.download = filename;
171
+ document.body.appendChild(el);
172
+ el.click();
173
+ document.body.removeChild(el);
174
+ resolve();
175
+ });
176
+ },
177
+ loadImage(src) {
178
+ return new Promise((resolve, reject) => {
179
+ const img = new Image();
180
+ const { suffix, crossOrigin } = Platform.image;
181
+ if (crossOrigin) {
182
+ img.setAttribute('crossOrigin', crossOrigin);
183
+ img.crossOrigin = crossOrigin;
184
+ }
185
+ img.onload = () => { resolve(img); };
186
+ img.onerror = (e) => { reject(e); };
187
+ if (!src.startsWith('data:') && !src.startsWith('blob:') && suffix)
188
+ src += (src.includes("?") ? "&" : "?") + suffix;
189
+ img.src = src;
190
+ });
191
+ }
192
+ };
193
+ Platform.event = {
194
+ stopDefault(origin) { origin.preventDefault(); },
195
+ stopNow(origin) { origin.stopImmediatePropagation(); },
196
+ stop(origin) { origin.stopPropagation(); }
197
+ };
198
+ Platform.canvas = Creator.canvas();
199
+ Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
200
+ }
201
+ Platform.name = 'web';
202
+ Platform.isMobile = 'ontouchstart' in window;
203
+ Platform.requestRender = function (render) { window.requestAnimationFrame(render); };
204
+ Platform.devicePixelRatio = Math.max(1, devicePixelRatio);
205
+ const { userAgent } = navigator;
206
+ if (userAgent.indexOf("Firefox") > -1) {
207
+ Platform.conicGradientRotate90 = true;
208
+ Platform.intWheelDeltaY = true;
209
+ Platform.syncDomFont = true;
210
+ }
211
+ else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
212
+ Platform.fullImageShadow = true;
213
+ }
214
+ if (userAgent.indexOf('Windows') > -1) {
215
+ Platform.os = 'Windows';
216
+ Platform.intWheelDeltaY = true;
217
+ }
218
+ else if (userAgent.indexOf('Mac') > -1) {
219
+ Platform.os = 'Mac';
220
+ }
221
+ else if (userAgent.indexOf('Linux') > -1) {
222
+ Platform.os = 'Linux';
223
+ }
224
+
225
+ class Watcher {
226
+ get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
227
+ get updatedList() {
228
+ if (this.hasRemove) {
229
+ const updatedList = new LeafList();
230
+ this.__updatedList.list.forEach(item => { if (item.leafer)
231
+ updatedList.add(item); });
232
+ return updatedList;
233
+ }
234
+ else {
235
+ return this.__updatedList;
236
+ }
237
+ }
238
+ constructor(target, userConfig) {
239
+ this.totalTimes = 0;
240
+ this.config = {};
241
+ this.__updatedList = new LeafList();
242
+ this.target = target;
243
+ if (userConfig)
244
+ this.config = DataHelper.default(userConfig, this.config);
245
+ this.__listenEvents();
246
+ }
247
+ start() {
248
+ if (this.disabled)
249
+ return;
250
+ this.running = true;
251
+ }
252
+ stop() {
253
+ this.running = false;
254
+ }
255
+ disable() {
256
+ this.stop();
257
+ this.__removeListenEvents();
258
+ this.disabled = true;
259
+ }
260
+ update() {
261
+ this.changed = true;
262
+ if (this.running)
263
+ this.target.emit(RenderEvent.REQUEST);
264
+ }
265
+ __onAttrChange(event) {
266
+ this.__updatedList.add(event.target);
267
+ this.update();
268
+ }
269
+ __onChildEvent(event) {
270
+ if (event.type === ChildEvent.ADD) {
271
+ this.hasAdd = true;
272
+ this.__pushChild(event.child);
273
+ }
274
+ else {
275
+ this.hasRemove = true;
276
+ this.__updatedList.add(event.parent);
277
+ }
278
+ this.update();
279
+ }
280
+ __pushChild(child) {
281
+ this.__updatedList.add(child);
282
+ if (child.isBranch)
283
+ this.__loopChildren(child);
284
+ }
285
+ __loopChildren(parent) {
286
+ const { children } = parent;
287
+ for (let i = 0, len = children.length; i < len; i++)
288
+ this.__pushChild(children[i]);
289
+ }
290
+ __onRquestData() {
291
+ this.target.emitEvent(new WatchEvent(WatchEvent.DATA, { updatedList: this.updatedList }));
292
+ this.__updatedList = new LeafList();
293
+ this.totalTimes++;
294
+ this.changed = false;
295
+ this.hasVisible = false;
296
+ this.hasRemove = false;
297
+ this.hasAdd = false;
298
+ }
299
+ __listenEvents() {
300
+ const { target } = this;
301
+ this.__eventIds = [
302
+ target.on_(PropertyEvent.CHANGE, this.__onAttrChange, this),
303
+ target.on_([ChildEvent.ADD, ChildEvent.REMOVE], this.__onChildEvent, this),
304
+ target.on_(WatchEvent.REQUEST, this.__onRquestData, this)
305
+ ];
306
+ }
307
+ __removeListenEvents() {
308
+ this.target.off_(this.__eventIds);
309
+ }
310
+ destroy() {
311
+ if (this.target) {
312
+ this.stop();
313
+ this.__removeListenEvents();
314
+ this.target = null;
315
+ this.__updatedList = null;
316
+ }
317
+ }
318
+ }
319
+
320
+ const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateAllWorldOpacity } = LeafHelper;
321
+ const { pushAllChildBranch, pushAllParent } = BranchHelper;
322
+ function updateMatrix(updateList, levelList) {
323
+ let layout;
324
+ updateList.list.forEach(leaf => {
325
+ layout = leaf.__layout;
326
+ if (levelList.without(leaf) && !layout.proxyZoom) {
327
+ if (layout.matrixChanged) {
328
+ updateAllMatrix$1(leaf, true);
329
+ levelList.add(leaf);
330
+ if (leaf.isBranch)
331
+ pushAllChildBranch(leaf, levelList);
332
+ pushAllParent(leaf, levelList);
333
+ }
334
+ else if (layout.boundsChanged) {
335
+ levelList.add(leaf);
336
+ if (leaf.isBranch)
337
+ leaf.__tempNumber = 0;
338
+ pushAllParent(leaf, levelList);
339
+ }
340
+ }
341
+ });
342
+ }
343
+ function updateBounds(boundsList) {
344
+ let list, branch, children;
345
+ boundsList.sort(true);
346
+ boundsList.levels.forEach(level => {
347
+ list = boundsList.levelMap[level];
348
+ for (let i = 0, len = list.length; i < len; i++) {
349
+ branch = list[i];
350
+ if (branch.isBranch && branch.__tempNumber) {
351
+ children = branch.children;
352
+ for (let j = 0, jLen = children.length; j < jLen; j++) {
353
+ if (!children[j].isBranch) {
354
+ updateOneBounds(children[j]);
355
+ }
356
+ }
357
+ }
358
+ updateOneBounds(branch);
359
+ }
360
+ });
361
+ }
362
+ function updateChange(updateList) {
363
+ updateList.list.forEach(leaf => {
364
+ if (leaf.__layout.opacityChanged)
365
+ updateAllWorldOpacity(leaf);
366
+ leaf.__updateChange();
367
+ });
368
+ }
369
+
370
+ const { worldBounds } = LeafBoundsHelper;
371
+ const bigBounds = { x: 0, y: 0, width: 100000, height: 100000 };
372
+ class LayoutBlockData {
373
+ constructor(list) {
374
+ this.updatedBounds = new Bounds();
375
+ this.beforeBounds = new Bounds();
376
+ this.afterBounds = new Bounds();
377
+ if (list instanceof Array)
378
+ list = new LeafList(list);
379
+ this.updatedList = list;
380
+ }
381
+ setBefore() {
382
+ this.beforeBounds.setListWithFn(this.updatedList.list, worldBounds);
383
+ }
384
+ setAfter() {
385
+ const { list } = this.updatedList;
386
+ if (list.some(leaf => leaf.noBounds)) {
387
+ this.afterBounds.set(bigBounds);
388
+ }
389
+ else {
390
+ this.afterBounds.setListWithFn(list, worldBounds);
391
+ }
392
+ this.updatedBounds.setList([this.beforeBounds, this.afterBounds]);
393
+ }
394
+ merge(data) {
395
+ this.updatedList.addList(data.updatedList.list);
396
+ this.beforeBounds.add(data.beforeBounds);
397
+ this.afterBounds.add(data.afterBounds);
398
+ this.updatedBounds.add(data.updatedBounds);
399
+ }
400
+ destroy() {
401
+ this.updatedList = null;
402
+ }
403
+ }
404
+
405
+ const { updateAllMatrix, updateAllChange } = LeafHelper;
406
+ const debug$1 = Debug.get('Layouter');
407
+ class Layouter {
408
+ constructor(target, userConfig) {
409
+ this.totalTimes = 0;
410
+ this.config = {};
411
+ this.__levelList = new LeafLevelList();
412
+ this.target = target;
413
+ if (userConfig)
414
+ this.config = DataHelper.default(userConfig, this.config);
415
+ this.__listenEvents();
416
+ }
417
+ start() {
418
+ if (this.disabled)
419
+ return;
420
+ this.running = true;
421
+ }
422
+ stop() {
423
+ this.running = false;
424
+ }
425
+ disable() {
426
+ this.stop();
427
+ this.__removeListenEvents();
428
+ this.disabled = true;
429
+ }
430
+ layout() {
431
+ if (!this.running)
432
+ return;
433
+ const { target } = this;
434
+ this.times = 0;
435
+ try {
436
+ target.emit(LayoutEvent.START);
437
+ this.layoutOnce();
438
+ target.emitEvent(new LayoutEvent(LayoutEvent.END, this.layoutedBlocks, this.times));
439
+ }
440
+ catch (e) {
441
+ debug$1.error(e);
442
+ }
443
+ this.layoutedBlocks = null;
444
+ }
445
+ layoutAgain() {
446
+ if (this.layouting) {
447
+ this.waitAgain = true;
448
+ }
449
+ else {
450
+ this.layoutOnce();
451
+ }
452
+ }
453
+ layoutOnce() {
454
+ if (this.layouting)
455
+ return debug$1.warn('layouting');
456
+ if (this.times > 3)
457
+ return debug$1.warn('layout max times');
458
+ this.times++;
459
+ this.totalTimes++;
460
+ this.layouting = true;
461
+ this.target.emit(WatchEvent.REQUEST);
462
+ if (this.totalTimes > 1) {
463
+ this.partLayout();
464
+ }
465
+ else {
466
+ this.fullLayout();
467
+ }
468
+ this.layouting = false;
469
+ if (this.waitAgain) {
470
+ this.waitAgain = false;
471
+ this.layoutOnce();
472
+ }
473
+ }
474
+ partLayout() {
475
+ var _a;
476
+ if (!((_a = this.__updatedList) === null || _a === void 0 ? void 0 : _a.length))
477
+ return;
478
+ const t = Run.start('PartLayout');
479
+ const { target, __updatedList: updateList } = this;
480
+ const { BEFORE, LAYOUT, AFTER } = LayoutEvent;
481
+ const blocks = this.getBlocks(updateList);
482
+ blocks.forEach(item => item.setBefore());
483
+ target.emitEvent(new LayoutEvent(BEFORE, blocks, this.times));
484
+ this.extraBlock = null;
485
+ updateList.sort();
486
+ updateMatrix(updateList, this.__levelList);
487
+ updateBounds(this.__levelList);
488
+ updateChange(updateList);
489
+ if (this.extraBlock)
490
+ blocks.push(this.extraBlock);
491
+ blocks.forEach(item => item.setAfter());
492
+ target.emitEvent(new LayoutEvent(LAYOUT, blocks, this.times));
493
+ target.emitEvent(new LayoutEvent(AFTER, blocks, this.times));
494
+ this.addBlocks(blocks);
495
+ this.__levelList.reset();
496
+ this.__updatedList = null;
497
+ Run.end(t);
498
+ }
499
+ fullLayout() {
500
+ const t = Run.start('FullLayout');
501
+ const { target } = this;
502
+ const { BEFORE, LAYOUT, AFTER } = LayoutEvent;
503
+ const blocks = this.getBlocks(new LeafList(target));
504
+ target.emitEvent(new LayoutEvent(BEFORE, blocks, this.times));
505
+ Layouter.fullLayout(target);
506
+ blocks.forEach(item => { item.setAfter(); });
507
+ target.emitEvent(new LayoutEvent(LAYOUT, blocks, this.times));
508
+ target.emitEvent(new LayoutEvent(AFTER, blocks, this.times));
509
+ this.addBlocks(blocks);
510
+ Run.end(t);
511
+ }
512
+ static fullLayout(target) {
513
+ updateAllMatrix(target, true);
514
+ if (target.isBranch) {
515
+ BranchHelper.updateBounds(target);
516
+ }
517
+ else {
518
+ LeafHelper.updateBounds(target);
519
+ }
520
+ updateAllChange(target);
521
+ }
522
+ addExtra(leaf) {
523
+ const block = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
524
+ block.updatedList.add(leaf);
525
+ block.beforeBounds.add(leaf.__world);
526
+ }
527
+ createBlock(data) {
528
+ return new LayoutBlockData(data);
529
+ }
530
+ getBlocks(list) {
531
+ return [this.createBlock(list)];
532
+ }
533
+ addBlocks(current) {
534
+ this.layoutedBlocks ? this.layoutedBlocks.push(...current) : this.layoutedBlocks = current;
535
+ }
536
+ __onReceiveWatchData(event) {
537
+ this.__updatedList = event.data.updatedList;
538
+ }
539
+ __listenEvents() {
540
+ const { target } = this;
541
+ this.__eventIds = [
542
+ target.on_(LayoutEvent.REQUEST, this.layout, this),
543
+ target.on_(LayoutEvent.AGAIN, this.layoutAgain, this),
544
+ target.on_(WatchEvent.DATA, this.__onReceiveWatchData, this)
545
+ ];
546
+ }
547
+ __removeListenEvents() {
548
+ this.target.off_(this.__eventIds);
549
+ }
550
+ destroy() {
551
+ if (this.target) {
552
+ this.stop();
553
+ this.__removeListenEvents();
554
+ this.target = this.config = null;
555
+ }
556
+ }
557
+ }
558
+
559
+ const debug = Debug.get('Renderer');
560
+ class Renderer {
561
+ get needFill() { return !!(!this.canvas.allowBackgroundColor && this.config.fill); }
562
+ constructor(target, canvas, userConfig) {
563
+ this.FPS = 60;
564
+ this.totalTimes = 0;
565
+ this.times = 0;
566
+ this.config = {
567
+ usePartRender: true,
568
+ maxFPS: 60
569
+ };
570
+ this.target = target;
571
+ this.canvas = canvas;
572
+ if (userConfig)
573
+ this.config = DataHelper.default(userConfig, this.config);
574
+ this.__listenEvents();
575
+ this.__requestRender();
576
+ }
577
+ start() {
578
+ this.running = true;
579
+ }
580
+ stop() {
581
+ this.running = false;
582
+ }
583
+ update() {
584
+ this.changed = true;
585
+ }
586
+ requestLayout() {
587
+ this.target.emit(LayoutEvent.REQUEST);
588
+ }
589
+ render(callback) {
590
+ if (!(this.running && this.canvas.view)) {
591
+ this.changed = true;
592
+ return;
593
+ }
594
+ const { target } = this;
595
+ this.times = 0;
596
+ this.totalBounds = new Bounds();
597
+ debug.log(target.innerName, '--->');
598
+ try {
599
+ this.emitRender(RenderEvent.START);
600
+ this.renderOnce(callback);
601
+ this.emitRender(RenderEvent.END, this.totalBounds);
602
+ ImageManager.clearRecycled();
603
+ }
604
+ catch (e) {
605
+ this.rendering = false;
606
+ debug.error(e);
607
+ }
608
+ debug.log('-------------|');
609
+ }
610
+ renderAgain() {
611
+ if (this.rendering) {
612
+ this.waitAgain = true;
613
+ }
614
+ else {
615
+ this.renderOnce();
616
+ }
617
+ }
618
+ renderOnce(callback) {
619
+ if (this.rendering)
620
+ return debug.warn('rendering');
621
+ if (this.times > 3)
622
+ return debug.warn('render max times');
623
+ this.times++;
624
+ this.totalTimes++;
625
+ this.rendering = true;
626
+ this.changed = false;
627
+ this.renderBounds = new Bounds();
628
+ this.renderOptions = {};
629
+ if (callback) {
630
+ this.emitRender(RenderEvent.BEFORE);
631
+ callback();
632
+ }
633
+ else {
634
+ this.requestLayout();
635
+ this.emitRender(RenderEvent.BEFORE);
636
+ if (this.config.usePartRender && this.totalTimes > 1) {
637
+ this.partRender();
638
+ }
639
+ else {
640
+ this.fullRender();
641
+ }
642
+ }
643
+ this.emitRender(RenderEvent.RENDER, this.renderBounds, this.renderOptions);
644
+ this.emitRender(RenderEvent.AFTER, this.renderBounds, this.renderOptions);
645
+ this.updateBlocks = null;
646
+ this.rendering = false;
647
+ if (this.waitAgain) {
648
+ this.waitAgain = false;
649
+ this.renderOnce();
650
+ }
651
+ }
652
+ partRender() {
653
+ const { canvas, updateBlocks: list } = this;
654
+ if (!list)
655
+ return debug.warn('PartRender: need update attr');
656
+ this.mergeBlocks();
657
+ list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
658
+ this.clipRender(block); });
659
+ }
660
+ clipRender(block) {
661
+ const t = Run.start('PartRender');
662
+ const { canvas } = this;
663
+ const bounds = block.getIntersect(canvas.bounds);
664
+ const includes = block.includes(this.target.__world);
665
+ const realBounds = new Bounds(bounds);
666
+ canvas.save();
667
+ if (includes && !Debug.showRepaint) {
668
+ canvas.clear();
669
+ }
670
+ else {
671
+ bounds.spread(1 + 1 / this.canvas.pixelRatio).ceil();
672
+ canvas.clearWorld(bounds, true);
673
+ canvas.clipWorld(bounds, true);
674
+ }
675
+ this.__render(bounds, includes, realBounds);
676
+ canvas.restore();
677
+ Run.end(t);
678
+ }
679
+ fullRender() {
680
+ const t = Run.start('FullRender');
681
+ const { canvas } = this;
682
+ canvas.save();
683
+ canvas.clear();
684
+ this.__render(canvas.bounds, true);
685
+ canvas.restore();
686
+ Run.end(t);
687
+ }
688
+ __render(bounds, includes, realBounds) {
689
+ const options = bounds.includes(this.target.__world) ? { includes } : { bounds, includes };
690
+ if (this.needFill)
691
+ this.canvas.fillWorld(bounds, this.config.fill);
692
+ if (Debug.showRepaint)
693
+ this.canvas.strokeWorld(bounds, 'red');
694
+ this.target.__render(this.canvas, options);
695
+ this.renderBounds = realBounds || bounds;
696
+ this.renderOptions = options;
697
+ this.totalBounds.isEmpty() ? this.totalBounds = this.renderBounds : this.totalBounds.add(this.renderBounds);
698
+ if (Debug.showHitView)
699
+ this.renderHitView(options);
700
+ if (Debug.showBoundsView)
701
+ this.renderBoundsView(options);
702
+ this.canvas.updateRender();
703
+ }
704
+ renderHitView(_options) { }
705
+ renderBoundsView(_options) { }
706
+ addBlock(block) {
707
+ if (!this.updateBlocks)
708
+ this.updateBlocks = [];
709
+ this.updateBlocks.push(block);
710
+ }
711
+ mergeBlocks() {
712
+ const { updateBlocks: list } = this;
713
+ if (list) {
714
+ const bounds = new Bounds();
715
+ bounds.setList(list);
716
+ list.length = 0;
717
+ list.push(bounds);
718
+ }
719
+ }
720
+ __requestRender() {
721
+ const startTime = Date.now();
722
+ Platform.requestRender(() => {
723
+ this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - startTime)));
724
+ if (this.running) {
725
+ this.target.emit(AnimateEvent.FRAME);
726
+ if (this.changed && this.canvas.view)
727
+ this.render();
728
+ this.target.emit(RenderEvent.NEXT);
729
+ }
730
+ if (this.target)
731
+ this.__requestRender();
732
+ });
733
+ }
734
+ __onResize(e) {
735
+ if (this.canvas.unreal)
736
+ return;
737
+ if (e.bigger || !e.samePixelRatio) {
738
+ const { width, height } = e.old;
739
+ const bounds = new Bounds(0, 0, width, height);
740
+ if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
741
+ this.addBlock(this.canvas.bounds);
742
+ this.target.forceUpdate('surface');
743
+ }
744
+ }
745
+ }
746
+ __onLayoutEnd(event) {
747
+ if (event.data)
748
+ event.data.map(item => {
749
+ let empty;
750
+ if (item.updatedList)
751
+ item.updatedList.list.some(leaf => {
752
+ empty = (!leaf.__world.width || !leaf.__world.height);
753
+ if (empty) {
754
+ if (!leaf.isLeafer)
755
+ debug.tip(leaf.innerName, ': empty');
756
+ empty = (!leaf.isBranch || leaf.isBranchLeaf);
757
+ }
758
+ return empty;
759
+ });
760
+ this.addBlock(empty ? this.canvas.bounds : item.updatedBounds);
761
+ });
762
+ }
763
+ emitRender(type, bounds, options) {
764
+ this.target.emitEvent(new RenderEvent(type, this.times, bounds, options));
765
+ }
766
+ __listenEvents() {
767
+ const { target } = this;
768
+ this.__eventIds = [
769
+ target.on_(RenderEvent.REQUEST, this.update, this),
770
+ target.on_(LayoutEvent.END, this.__onLayoutEnd, this),
771
+ target.on_(RenderEvent.AGAIN, this.renderAgain, this),
772
+ target.on_(ResizeEvent.RESIZE, this.__onResize, this)
773
+ ];
774
+ }
775
+ __removeListenEvents() {
776
+ this.target.off_(this.__eventIds);
777
+ }
778
+ destroy() {
779
+ if (this.target) {
780
+ this.stop();
781
+ this.__removeListenEvents();
782
+ this.target = null;
783
+ this.canvas = null;
784
+ this.config = null;
785
+ }
786
+ }
787
+ }
788
+
789
+ const { hitRadiusPoint } = BoundsHelper;
790
+ class Picker {
791
+ constructor(target, selector) {
792
+ this.target = target;
793
+ this.selector = selector;
794
+ }
795
+ getByPoint(hitPoint, hitRadius, options) {
796
+ if (!hitRadius)
797
+ hitRadius = 0;
798
+ if (!options)
799
+ options = {};
800
+ const through = options.through || false;
801
+ const ignoreHittable = options.ignoreHittable || false;
802
+ const target = options.target || this.target;
803
+ this.exclude = options.exclude || null;
804
+ this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius };
805
+ this.findList = options.findList || [];
806
+ if (!options.findList)
807
+ this.eachFind(target.children, target.__onlyHitMask);
808
+ const list = this.findList;
809
+ const leaf = this.getBestMatchLeaf();
810
+ const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf);
811
+ this.clear();
812
+ return through ? { path, target: leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, target: leaf };
813
+ }
814
+ getBestMatchLeaf() {
815
+ const { findList: targets } = this;
816
+ if (targets.length > 1) {
817
+ let find;
818
+ this.findList = [];
819
+ const { x, y } = this.point;
820
+ const point = { x, y, radiusX: 0, radiusY: 0 };
821
+ for (let i = 0, len = targets.length; i < len; i++) {
822
+ find = targets[i];
823
+ if (LeafHelper.worldHittable(find)) {
824
+ this.hitChild(find, point);
825
+ if (this.findList.length)
826
+ return this.findList[0];
827
+ }
828
+ }
829
+ }
830
+ return targets[0];
831
+ }
832
+ getPath(leaf) {
833
+ const path = new LeafList();
834
+ while (leaf) {
835
+ path.add(leaf);
836
+ leaf = leaf.parent;
837
+ }
838
+ path.add(this.target);
839
+ return path;
840
+ }
841
+ getHitablePath(leaf) {
842
+ const path = this.getPath(leaf);
843
+ let item, hittablePath = new LeafList();
844
+ for (let i = path.list.length - 1; i > -1; i--) {
845
+ item = path.list[i];
846
+ if (!item.__.hittable)
847
+ break;
848
+ hittablePath.addAt(item, 0);
849
+ if (!item.__.hitChildren)
850
+ break;
851
+ }
852
+ return hittablePath;
853
+ }
854
+ getThroughPath(list) {
855
+ const throughPath = new LeafList();
856
+ const pathList = [];
857
+ for (let i = list.length - 1; i > -1; i--) {
858
+ pathList.push(this.getPath(list[i]));
859
+ }
860
+ let path, nextPath, leaf;
861
+ for (let i = 0, len = pathList.length; i < len; i++) {
862
+ path = pathList[i], nextPath = pathList[i + 1];
863
+ for (let j = 0, jLen = path.length; j < jLen; j++) {
864
+ leaf = path.list[j];
865
+ if (nextPath && nextPath.has(leaf))
866
+ break;
867
+ throughPath.add(leaf);
868
+ }
869
+ }
870
+ return throughPath;
871
+ }
872
+ eachFind(children, hitMask) {
873
+ let child, hit;
874
+ const { point } = this, len = children.length;
875
+ for (let i = len - 1; i > -1; i--) {
876
+ child = children[i];
877
+ if (!child.__.visible || (hitMask && !child.__.mask))
878
+ continue;
879
+ hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
880
+ if (child.isBranch) {
881
+ if (hit || child.__ignoreHitWorld) {
882
+ this.eachFind(child.children, child.__onlyHitMask);
883
+ if (child.isBranchLeaf && !this.findList.length)
884
+ this.hitChild(child, point);
885
+ }
886
+ }
887
+ else {
888
+ if (hit)
889
+ this.hitChild(child, point);
890
+ }
891
+ }
892
+ }
893
+ hitChild(child, point) {
894
+ if (this.exclude && this.exclude.has(child))
895
+ return;
896
+ if (child.__hitWorld(point))
897
+ this.findList.push(child);
898
+ }
899
+ clear() {
900
+ this.point = null;
901
+ this.findList = null;
902
+ this.exclude = null;
903
+ }
904
+ destroy() {
905
+ this.clear();
906
+ }
907
+ }
908
+
909
+ const { Yes, NoAndSkip, YesAndSkip } = Answer;
910
+ class Selector {
911
+ constructor(target, userConfig) {
912
+ this.config = {};
913
+ this.innerIdMap = {};
914
+ this.idMap = {};
915
+ this.methods = {
916
+ id: (leaf, name) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
917
+ innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
918
+ className: (leaf, name) => leaf.className === name ? 1 : 0,
919
+ tag: (leaf, name) => leaf.__tag === name ? 1 : 0
920
+ };
921
+ this.target = target;
922
+ if (userConfig)
923
+ this.config = DataHelper.default(userConfig, this.config);
924
+ this.picker = new Picker(target, this);
925
+ this.__listenEvents();
926
+ }
927
+ getBy(condition, branch, one, options) {
928
+ switch (typeof condition) {
929
+ case 'number':
930
+ const leaf = this.getByInnerId(condition, branch);
931
+ return one ? leaf : (leaf ? [leaf] : []);
932
+ case 'string':
933
+ switch (condition[0]) {
934
+ case '#':
935
+ const leaf = this.getById(condition.substring(1), branch);
936
+ return one ? leaf : (leaf ? [leaf] : []);
937
+ case '.':
938
+ return this.getByMethod(this.methods.className, branch, one, condition.substring(1));
939
+ default:
940
+ return this.getByMethod(this.methods.tag, branch, one, condition);
941
+ }
942
+ case 'function':
943
+ return this.getByMethod(condition, branch, one, options);
944
+ }
945
+ }
946
+ getByPoint(hitPoint, hitRadius, options) {
947
+ if (Platform.name === 'node')
948
+ this.target.emit(LayoutEvent.CHECK_UPDATE);
949
+ return this.picker.getByPoint(hitPoint, hitRadius, options);
950
+ }
951
+ getByInnerId(innerId, branch) {
952
+ const cache = this.innerIdMap[innerId];
953
+ if (cache)
954
+ return cache;
955
+ this.eachFind(this.toChildren(branch), this.methods.innerId, null, innerId);
956
+ return this.findLeaf;
957
+ }
958
+ getById(id, branch) {
959
+ const cache = this.idMap[id];
960
+ if (cache && LeafHelper.hasParent(cache, branch || this.target))
961
+ return cache;
962
+ this.eachFind(this.toChildren(branch), this.methods.id, null, id);
963
+ return this.findLeaf;
964
+ }
965
+ getByClassName(className, branch) {
966
+ return this.getByMethod(this.methods.className, branch, false, className);
967
+ }
968
+ getByTag(tag, branch) {
969
+ return this.getByMethod(this.methods.tag, branch, false, tag);
970
+ }
971
+ getByMethod(method, branch, one, options) {
972
+ const list = one ? null : [];
973
+ this.eachFind(this.toChildren(branch), method, list, options);
974
+ return list || this.findLeaf;
975
+ }
976
+ eachFind(children, method, list, options) {
977
+ let child, result;
978
+ for (let i = 0, len = children.length; i < len; i++) {
979
+ child = children[i];
980
+ result = method(child, options);
981
+ if (result === Yes || result === YesAndSkip) {
982
+ if (list) {
983
+ list.push(child);
984
+ }
985
+ else {
986
+ this.findLeaf = child;
987
+ return;
988
+ }
989
+ }
990
+ if (child.isBranch && result < NoAndSkip)
991
+ this.eachFind(child.children, method, list, options);
992
+ }
993
+ }
994
+ toChildren(branch) {
995
+ this.findLeaf = null;
996
+ return [branch || this.target];
997
+ }
998
+ __onRemoveChild(event) {
999
+ const { id, innerId } = event.child;
1000
+ if (this.idMap[id])
1001
+ delete this.idMap[id];
1002
+ if (this.innerIdMap[innerId])
1003
+ delete this.innerIdMap[innerId];
1004
+ }
1005
+ __checkIdChange(event) {
1006
+ if (event.attrName === 'id') {
1007
+ const id = event.oldValue;
1008
+ if (this.idMap[id])
1009
+ delete this.idMap[id];
1010
+ }
1011
+ }
1012
+ __listenEvents() {
1013
+ this.__eventIds = [
1014
+ this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this),
1015
+ this.target.on_(PropertyEvent.CHANGE, this.__checkIdChange, this)
1016
+ ];
1017
+ }
1018
+ __removeListenEvents() {
1019
+ this.target.off_(this.__eventIds);
1020
+ this.__eventIds.length = 0;
1021
+ }
1022
+ destroy() {
1023
+ if (this.__eventIds.length) {
1024
+ this.__removeListenEvents();
1025
+ this.picker.destroy();
1026
+ this.findLeaf = null;
1027
+ this.innerIdMap = {};
1028
+ this.idMap = {};
1029
+ }
1030
+ }
1031
+ }
1032
+
1033
+ Object.assign(Creator, {
1034
+ watcher: (target, options) => new Watcher(target, options),
1035
+ layouter: (target, options) => new Layouter(target, options),
1036
+ renderer: (target, canvas, options) => new Renderer(target, canvas, options),
1037
+ selector: (target, options) => new Selector(target, options)
1038
+ });
1039
+ Platform.layout = Layouter.fullLayout;
1040
+
1041
+ const PointerEventHelper = {
1042
+ convert(e, local) {
1043
+ const base = InteractionHelper.getBase(e);
1044
+ const data = Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: e.width, height: e.height, pointerType: e.pointerType, pressure: e.pressure });
1045
+ if (data.pointerType === 'pen') {
1046
+ data.tangentialPressure = e.tangentialPressure;
1047
+ data.tiltX = e.tiltX;
1048
+ data.tiltY = e.tiltY;
1049
+ data.twist = e.twist;
1050
+ }
1051
+ return data;
1052
+ },
1053
+ convertMouse(e, local) {
1054
+ const base = InteractionHelper.getBase(e);
1055
+ return Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: 1, height: 1, pointerType: 'mouse', pressure: 0.5 });
1056
+ },
1057
+ convertTouch(e, local) {
1058
+ const touch = PointerEventHelper.getTouch(e);
1059
+ const base = InteractionHelper.getBase(e);
1060
+ return Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: 1, height: 1, pointerType: 'touch', pressure: touch.force });
1061
+ },
1062
+ getTouch(e) {
1063
+ return e.targetTouches[0] || e.changedTouches[0];
1064
+ }
1065
+ };
1066
+
1067
+ const WheelEventHelper = {
1068
+ getMove(e, config) {
1069
+ let { moveSpeed } = config;
1070
+ let { deltaX, deltaY } = e;
1071
+ if (e.shiftKey && !deltaX) {
1072
+ deltaX = deltaY;
1073
+ deltaY = 0;
1074
+ }
1075
+ if (deltaX > 50)
1076
+ deltaX = Math.max(50, deltaX / 3);
1077
+ if (deltaY > 50)
1078
+ deltaY = Math.max(50, deltaY / 3);
1079
+ return { x: -deltaX * moveSpeed * 2, y: -deltaY * moveSpeed * 2 };
1080
+ },
1081
+ getScale(e, config) {
1082
+ let zoom;
1083
+ let scale = 1;
1084
+ let { zoomMode, zoomSpeed } = config;
1085
+ const delta = e.deltaY || e.deltaX;
1086
+ if (zoomMode) {
1087
+ zoom = (zoomMode === 'mouse') ? true : (!e.deltaX && (Platform$1.intWheelDeltaY ? Math.abs(delta) > 17 : Math.ceil(delta) !== delta));
1088
+ if (e.shiftKey || e.metaKey || e.ctrlKey)
1089
+ zoom = true;
1090
+ }
1091
+ else {
1092
+ zoom = !e.shiftKey && (e.metaKey || e.ctrlKey);
1093
+ }
1094
+ if (zoom) {
1095
+ zoomSpeed = MathHelper.within(zoomSpeed, 0, 1);
1096
+ const min = e.deltaY ? config.delta.y : config.delta.x;
1097
+ scale = 1 - delta / (min * 4) * zoomSpeed;
1098
+ if (scale < 0.5)
1099
+ scale = 0.5;
1100
+ if (scale >= 1.5)
1101
+ scale = 1.5;
1102
+ }
1103
+ return scale;
1104
+ }
1105
+ };
1106
+
1107
+ const KeyEventHelper = {
1108
+ convert(e) {
1109
+ const base = InteractionHelper.getBase(e);
1110
+ const data = Object.assign(Object.assign({}, base), { code: e.code, key: e.key });
1111
+ return data;
1112
+ }
1113
+ };
1114
+
1115
+ const { getMoveEventData, getZoomEventData, getRotateEventData } = InteractionHelper;
1116
+ class Interaction extends InteractionBase {
1117
+ __listenEvents() {
1118
+ super.__listenEvents();
1119
+ const view = this.view = this.canvas.view;
1120
+ this.viewEvents = {
1121
+ 'pointerdown': this.onPointerDown,
1122
+ 'mousedown': this.onMouseDown,
1123
+ 'touchstart': this.onTouchStart,
1124
+ 'contextmenu': this.onContextMenu,
1125
+ 'wheel': this.onWheel,
1126
+ 'gesturestart': this.onGesturestart,
1127
+ 'gesturechange': this.onGesturechange,
1128
+ 'gestureend': this.onGestureend
1129
+ };
1130
+ this.windowEvents = {
1131
+ 'pointermove': this.onPointerMove,
1132
+ 'pointerup': this.onPointerUp,
1133
+ 'pointercancel': this.onPointerCancel,
1134
+ 'mousemove': this.onMouseMove,
1135
+ 'mouseup': this.onMouseUp,
1136
+ 'touchmove': this.onTouchMove,
1137
+ 'touchend': this.onTouchEnd,
1138
+ 'touchcancel': this.onTouchCancel,
1139
+ 'keydown': this.onKeyDown,
1140
+ 'keyup': this.onKeyUp,
1141
+ 'scroll': this.onScroll
1142
+ };
1143
+ const { viewEvents, windowEvents } = this;
1144
+ for (let name in viewEvents) {
1145
+ viewEvents[name] = viewEvents[name].bind(this);
1146
+ view.addEventListener(name, viewEvents[name]);
1147
+ }
1148
+ for (let name in windowEvents) {
1149
+ windowEvents[name] = windowEvents[name].bind(this);
1150
+ window.addEventListener(name, windowEvents[name]);
1151
+ }
1152
+ }
1153
+ __removeListenEvents() {
1154
+ super.__removeListenEvents();
1155
+ const { viewEvents, windowEvents } = this;
1156
+ for (let name in viewEvents) {
1157
+ this.view.removeEventListener(name, viewEvents[name]);
1158
+ this.viewEvents = {};
1159
+ }
1160
+ for (let name in windowEvents) {
1161
+ window.removeEventListener(name, windowEvents[name]);
1162
+ this.windowEvents = {};
1163
+ }
1164
+ }
1165
+ getLocal(p, updateClient) {
1166
+ if (updateClient)
1167
+ this.canvas.updateClientBounds();
1168
+ const { clientBounds } = this.canvas;
1169
+ return { x: p.clientX - clientBounds.x, y: p.clientY - clientBounds.y };
1170
+ }
1171
+ getTouches(touches) {
1172
+ const list = [];
1173
+ for (let i = 0, len = touches.length; i < len; i++) {
1174
+ list.push(touches[i]);
1175
+ }
1176
+ return list;
1177
+ }
1178
+ preventDefaultPointer(e) {
1179
+ const { pointer } = this.config;
1180
+ if (pointer.preventDefault)
1181
+ e.preventDefault();
1182
+ }
1183
+ preventDefaultWheel(e) {
1184
+ const { wheel } = this.config;
1185
+ if (wheel.preventDefault)
1186
+ e.preventDefault();
1187
+ }
1188
+ preventWindowPointer(e) {
1189
+ return !this.downData && e.target !== this.view;
1190
+ }
1191
+ onKeyDown(e) {
1192
+ this.keyDown(KeyEventHelper.convert(e));
1193
+ }
1194
+ onKeyUp(e) {
1195
+ this.keyUp(KeyEventHelper.convert(e));
1196
+ }
1197
+ onContextMenu(e) {
1198
+ if (this.config.pointer.preventDefaultMenu)
1199
+ e.preventDefault();
1200
+ this.menu(PointerEventHelper.convert(e, this.getLocal(e)));
1201
+ }
1202
+ onScroll() {
1203
+ this.canvas.updateClientBounds();
1204
+ }
1205
+ onPointerDown(e) {
1206
+ this.preventDefaultPointer(e);
1207
+ this.usePointer || (this.usePointer = true);
1208
+ if (this.useMultiTouch)
1209
+ return;
1210
+ this.pointerDown(PointerEventHelper.convert(e, this.getLocal(e)));
1211
+ }
1212
+ onPointerMove(e) {
1213
+ this.usePointer || (this.usePointer = true);
1214
+ if (this.useMultiTouch || this.preventWindowPointer(e))
1215
+ return;
1216
+ this.pointerMove(PointerEventHelper.convert(e, this.getLocal(e, true)));
1217
+ }
1218
+ onPointerUp(e) {
1219
+ if (this.downData)
1220
+ this.preventDefaultPointer(e);
1221
+ if (this.useMultiTouch || this.preventWindowPointer(e))
1222
+ return;
1223
+ this.pointerUp(PointerEventHelper.convert(e, this.getLocal(e)));
1224
+ }
1225
+ onPointerCancel() {
1226
+ if (this.useMultiTouch)
1227
+ return;
1228
+ this.pointerCancel();
1229
+ }
1230
+ onMouseDown(e) {
1231
+ this.preventDefaultPointer(e);
1232
+ if (this.useTouch || this.usePointer)
1233
+ return;
1234
+ this.pointerDown(PointerEventHelper.convertMouse(e, this.getLocal(e)));
1235
+ }
1236
+ onMouseMove(e) {
1237
+ if (this.useTouch || this.usePointer || this.preventWindowPointer(e))
1238
+ return;
1239
+ this.pointerMove(PointerEventHelper.convertMouse(e, this.getLocal(e, true)));
1240
+ }
1241
+ onMouseUp(e) {
1242
+ if (this.downData)
1243
+ this.preventDefaultPointer(e);
1244
+ if (this.useTouch || this.usePointer || this.preventWindowPointer(e))
1245
+ return;
1246
+ this.pointerUp(PointerEventHelper.convertMouse(e, this.getLocal(e)));
1247
+ }
1248
+ onMouseCancel() {
1249
+ if (this.useTouch || this.usePointer)
1250
+ return;
1251
+ this.pointerCancel();
1252
+ }
1253
+ onTouchStart(e) {
1254
+ e.preventDefault();
1255
+ this.multiTouchStart(e);
1256
+ if (this.usePointer)
1257
+ return;
1258
+ if (this.touchTimer) {
1259
+ window.clearTimeout(this.touchTimer);
1260
+ this.touchTimer = 0;
1261
+ }
1262
+ this.useTouch = true;
1263
+ const touch = PointerEventHelper.getTouch(e);
1264
+ this.pointerDown(PointerEventHelper.convertTouch(e, this.getLocal(touch, true)));
1265
+ }
1266
+ onTouchMove(e) {
1267
+ this.multiTouchMove(e);
1268
+ if (this.usePointer || this.preventWindowPointer(e))
1269
+ return;
1270
+ const touch = PointerEventHelper.getTouch(e);
1271
+ this.pointerMove(PointerEventHelper.convertTouch(e, this.getLocal(touch)));
1272
+ }
1273
+ onTouchEnd(e) {
1274
+ this.multiTouchEnd();
1275
+ if (this.usePointer || this.preventWindowPointer(e))
1276
+ return;
1277
+ if (this.touchTimer)
1278
+ clearTimeout(this.touchTimer);
1279
+ this.touchTimer = setTimeout(() => {
1280
+ this.useTouch = false;
1281
+ }, 500);
1282
+ const touch = PointerEventHelper.getTouch(e);
1283
+ this.pointerUp(PointerEventHelper.convertTouch(e, this.getLocal(touch)));
1284
+ }
1285
+ onTouchCancel() {
1286
+ if (this.usePointer)
1287
+ return;
1288
+ this.pointerCancel();
1289
+ }
1290
+ multiTouchStart(e) {
1291
+ this.useMultiTouch = (e.touches.length >= 2);
1292
+ this.touches = this.useMultiTouch ? this.getTouches(e.touches) : undefined;
1293
+ if (this.useMultiTouch)
1294
+ this.pointerCancel();
1295
+ }
1296
+ multiTouchMove(e) {
1297
+ if (!this.useMultiTouch)
1298
+ return;
1299
+ if (e.touches.length > 1) {
1300
+ const touches = this.getTouches(e.touches);
1301
+ const list = this.getKeepTouchList(this.touches, touches);
1302
+ if (list.length > 1) {
1303
+ this.multiTouch(InteractionHelper.getBase(e), list);
1304
+ this.touches = touches;
1305
+ }
1306
+ }
1307
+ }
1308
+ multiTouchEnd() {
1309
+ this.touches = null;
1310
+ this.useMultiTouch = false;
1311
+ this.transformEnd();
1312
+ }
1313
+ getKeepTouchList(old, touches) {
1314
+ let to;
1315
+ const list = [];
1316
+ old.forEach(from => {
1317
+ to = touches.find(touch => touch.identifier === from.identifier);
1318
+ if (to)
1319
+ list.push({ from: this.getLocal(from), to: this.getLocal(to) });
1320
+ });
1321
+ return list;
1322
+ }
1323
+ getLocalTouchs(points) {
1324
+ return points.map(point => this.getLocal(point));
1325
+ }
1326
+ onWheel(e) {
1327
+ this.preventDefaultWheel(e);
1328
+ const { wheel } = this.config;
1329
+ const scale = wheel.getScale ? wheel.getScale(e, wheel) : WheelEventHelper.getScale(e, wheel);
1330
+ const local = this.getLocal(e);
1331
+ const eventBase = InteractionHelper.getBase(e);
1332
+ scale !== 1 ? this.zoom(getZoomEventData(local, scale, eventBase)) : this.move(getMoveEventData(local, wheel.getMove ? wheel.getMove(e, wheel) : WheelEventHelper.getMove(e, wheel), eventBase));
1333
+ }
1334
+ onGesturestart(e) {
1335
+ this.preventDefaultWheel(e);
1336
+ this.lastGestureScale = 1;
1337
+ this.lastGestureRotation = 0;
1338
+ }
1339
+ onGesturechange(e) {
1340
+ this.preventDefaultWheel(e);
1341
+ const local = this.getLocal(e);
1342
+ const eventBase = InteractionHelper.getBase(e);
1343
+ const changeScale = e.scale / this.lastGestureScale;
1344
+ const changeAngle = e.rotation - this.lastGestureRotation;
1345
+ let { rotateSpeed } = this.config.wheel;
1346
+ rotateSpeed = MathHelper.within(rotateSpeed, 0, 1);
1347
+ this.zoom(getZoomEventData(local, changeScale * changeScale, eventBase));
1348
+ this.rotate(getRotateEventData(local, changeAngle / Math.PI * 180 * (rotateSpeed / 4 + 0.1), eventBase));
1349
+ this.lastGestureScale = e.scale;
1350
+ this.lastGestureRotation = e.rotation;
1351
+ }
1352
+ onGestureend(e) {
1353
+ this.preventDefaultWheel(e);
1354
+ this.transformEnd();
1355
+ }
1356
+ setCursor(cursor) {
1357
+ super.setCursor(cursor);
1358
+ const list = [];
1359
+ this.eachCursor(cursor, list);
1360
+ if (typeof list[list.length - 1] === 'object')
1361
+ list.push('default');
1362
+ this.canvas.view.style.cursor = list.map(item => (typeof item === 'object') ? `url(${item.url}) ${item.x || 0} ${item.y || 0}` : item).join(',');
1363
+ }
1364
+ eachCursor(cursor, list, level = 0) {
1365
+ level++;
1366
+ if (cursor instanceof Array) {
1367
+ cursor.forEach(item => this.eachCursor(item, list, level));
1368
+ }
1369
+ else {
1370
+ const custom = typeof cursor === 'string' && Cursor.get(cursor);
1371
+ if (custom && level < 2) {
1372
+ this.eachCursor(custom, list, level);
1373
+ }
1374
+ else {
1375
+ list.push(cursor);
1376
+ }
1377
+ }
1378
+ }
1379
+ destroy() {
1380
+ if (this.view) {
1381
+ super.destroy();
1382
+ this.view = null;
1383
+ this.touches = null;
1384
+ }
1385
+ }
1386
+ }
1387
+
1388
+ const PaintImage = {};
1389
+ const PaintGradient = {};
1390
+
1391
+ function fillText(ui, canvas) {
1392
+ let row;
1393
+ const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1394
+ for (let i = 0, len = rows.length; i < len; i++) {
1395
+ row = rows[i];
1396
+ if (row.text) {
1397
+ canvas.fillText(row.text, row.x, row.y);
1398
+ }
1399
+ else if (row.data) {
1400
+ row.data.forEach(charData => {
1401
+ canvas.fillText(charData.char, charData.x, row.y);
1402
+ });
1403
+ }
1404
+ if (decorationY)
1405
+ canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
1406
+ }
1407
+ }
1408
+
1409
+ function fill(fill, ui, canvas) {
1410
+ canvas.fillStyle = fill;
1411
+ ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
1412
+ }
1413
+ function fills(fills, ui, canvas) {
1414
+ let item;
1415
+ const { windingRule, __font } = ui.__;
1416
+ for (let i = 0, len = fills.length; i < len; i++) {
1417
+ item = fills[i];
1418
+ if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
1419
+ continue;
1420
+ if (item.style) {
1421
+ canvas.fillStyle = item.style;
1422
+ if (item.transform) {
1423
+ canvas.save();
1424
+ canvas.transform(item.transform);
1425
+ if (item.blendMode)
1426
+ canvas.blendMode = item.blendMode;
1427
+ __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1428
+ canvas.restore();
1429
+ }
1430
+ else {
1431
+ if (item.blendMode) {
1432
+ canvas.saveBlendMode(item.blendMode);
1433
+ __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1434
+ canvas.restoreBlendMode();
1435
+ }
1436
+ else {
1437
+ __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1438
+ }
1439
+ }
1440
+ }
1441
+ }
1442
+ }
1443
+
1444
+ function strokeText(stroke, ui, canvas) {
1445
+ const { strokeAlign } = ui.__;
1446
+ const isStrokes = typeof stroke !== 'string';
1447
+ switch (strokeAlign) {
1448
+ case 'center':
1449
+ canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
1450
+ isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
1451
+ break;
1452
+ case 'inside':
1453
+ drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
1454
+ break;
1455
+ case 'outside':
1456
+ drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
1457
+ break;
1458
+ }
1459
+ }
1460
+ function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
1461
+ const { __strokeWidth, __font } = ui.__;
1462
+ const out = canvas.getSameCanvas(true, true);
1463
+ out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
1464
+ out.font = __font;
1465
+ isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
1466
+ out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
1467
+ fillText(ui, out);
1468
+ out.blendMode = 'normal';
1469
+ if (ui.__worldFlipped) {
1470
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1471
+ }
1472
+ else {
1473
+ canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
1474
+ }
1475
+ out.recycle(ui.__nowWorld);
1476
+ }
1477
+ function drawTextStroke(ui, canvas) {
1478
+ let row;
1479
+ const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1480
+ for (let i = 0, len = rows.length; i < len; i++) {
1481
+ row = rows[i];
1482
+ if (row.text) {
1483
+ canvas.strokeText(row.text, row.x, row.y);
1484
+ }
1485
+ else if (row.data) {
1486
+ row.data.forEach(charData => {
1487
+ canvas.strokeText(charData.char, charData.x, row.y);
1488
+ });
1489
+ }
1490
+ if (decorationY)
1491
+ canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
1492
+ }
1493
+ }
1494
+ function drawStrokesStyle(strokes, isText, ui, canvas) {
1495
+ let item;
1496
+ for (let i = 0, len = strokes.length; i < len; i++) {
1497
+ item = strokes[i];
1498
+ if (item.image && PaintImage.checkImage(ui, canvas, item, false))
1499
+ continue;
1500
+ if (item.style) {
1501
+ canvas.strokeStyle = item.style;
1502
+ if (item.blendMode) {
1503
+ canvas.saveBlendMode(item.blendMode);
1504
+ isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1505
+ canvas.restoreBlendMode();
1506
+ }
1507
+ else {
1508
+ isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1509
+ }
1510
+ }
1511
+ }
1512
+ }
1513
+
1514
+ function stroke(stroke, ui, canvas) {
1515
+ const options = ui.__;
1516
+ const { __strokeWidth, strokeAlign, __font } = options;
1517
+ if (!__strokeWidth)
1518
+ return;
1519
+ if (__font) {
1520
+ strokeText(stroke, ui, canvas);
1521
+ }
1522
+ else {
1523
+ switch (strokeAlign) {
1524
+ case 'center':
1525
+ canvas.setStroke(stroke, __strokeWidth, options);
1526
+ canvas.stroke();
1527
+ break;
1528
+ case 'inside':
1529
+ canvas.save();
1530
+ canvas.setStroke(stroke, __strokeWidth * 2, options);
1531
+ options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1532
+ canvas.stroke();
1533
+ canvas.restore();
1534
+ break;
1535
+ case 'outside':
1536
+ const out = canvas.getSameCanvas(true, true);
1537
+ out.setStroke(stroke, __strokeWidth * 2, options);
1538
+ ui.__drawRenderPath(out);
1539
+ out.stroke();
1540
+ options.windingRule ? out.clip(options.windingRule) : out.clip();
1541
+ out.clearWorld(ui.__layout.renderBounds);
1542
+ if (ui.__worldFlipped) {
1543
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1544
+ }
1545
+ else {
1546
+ canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
1547
+ }
1548
+ out.recycle(ui.__nowWorld);
1549
+ break;
1550
+ }
1551
+ }
1552
+ }
1553
+ function strokes(strokes, ui, canvas) {
1554
+ const options = ui.__;
1555
+ const { __strokeWidth, strokeAlign, __font } = options;
1556
+ if (!__strokeWidth)
1557
+ return;
1558
+ if (__font) {
1559
+ strokeText(strokes, ui, canvas);
1560
+ }
1561
+ else {
1562
+ switch (strokeAlign) {
1563
+ case 'center':
1564
+ canvas.setStroke(undefined, __strokeWidth, options);
1565
+ drawStrokesStyle(strokes, false, ui, canvas);
1566
+ break;
1567
+ case 'inside':
1568
+ canvas.save();
1569
+ canvas.setStroke(undefined, __strokeWidth * 2, options);
1570
+ options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1571
+ drawStrokesStyle(strokes, false, ui, canvas);
1572
+ canvas.restore();
1573
+ break;
1574
+ case 'outside':
1575
+ const { renderBounds } = ui.__layout;
1576
+ const out = canvas.getSameCanvas(true, true);
1577
+ ui.__drawRenderPath(out);
1578
+ out.setStroke(undefined, __strokeWidth * 2, options);
1579
+ drawStrokesStyle(strokes, false, ui, out);
1580
+ options.windingRule ? out.clip(options.windingRule) : out.clip();
1581
+ out.clearWorld(renderBounds);
1582
+ if (ui.__worldFlipped) {
1583
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1584
+ }
1585
+ else {
1586
+ canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1587
+ }
1588
+ out.recycle(ui.__nowWorld);
1589
+ break;
1590
+ }
1591
+ }
1592
+ }
1593
+
1594
+ const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
1595
+ function shape(ui, current, options) {
1596
+ const canvas = current.getSameCanvas();
1597
+ const nowWorld = ui.__nowWorld;
1598
+ let bounds, fitMatrix, shapeBounds, worldCanvas;
1599
+ let { scaleX, scaleY } = nowWorld;
1600
+ if (scaleX < 0)
1601
+ scaleX = -scaleX;
1602
+ if (scaleY < 0)
1603
+ scaleY = -scaleY;
1604
+ if (current.bounds.includes(nowWorld)) {
1605
+ worldCanvas = canvas;
1606
+ bounds = shapeBounds = nowWorld;
1607
+ }
1608
+ else {
1609
+ const { renderShapeSpread: spread } = ui.__layout;
1610
+ const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, nowWorld);
1611
+ fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
1612
+ let { a: fitScaleX, d: fitScaleY } = fitMatrix;
1613
+ if (fitMatrix.a < 1) {
1614
+ worldCanvas = current.getSameCanvas();
1615
+ ui.__renderShape(worldCanvas, options);
1616
+ scaleX *= fitScaleX;
1617
+ scaleY *= fitScaleY;
1618
+ }
1619
+ shapeBounds = getOuterOf(nowWorld, fitMatrix);
1620
+ bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
1621
+ if (options.matrix) {
1622
+ const { matrix } = options;
1623
+ fitMatrix.multiply(matrix);
1624
+ fitScaleX *= matrix.scaleX;
1625
+ fitScaleY *= matrix.scaleY;
1626
+ }
1627
+ options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
1628
+ }
1629
+ ui.__renderShape(canvas, options);
1630
+ return {
1631
+ canvas, matrix: fitMatrix, bounds,
1632
+ worldCanvas, shapeBounds, scaleX, scaleY
1633
+ };
1634
+ }
1635
+
1636
+ let recycleMap;
1637
+ function compute(attrName, ui) {
1638
+ const data = ui.__, leafPaints = [];
1639
+ let paints = data.__input[attrName], hasOpacityPixel;
1640
+ if (!(paints instanceof Array))
1641
+ paints = [paints];
1642
+ recycleMap = PaintImage.recycleImage(attrName, data);
1643
+ for (let i = 0, len = paints.length, item; i < len; i++) {
1644
+ item = getLeafPaint(attrName, paints[i], ui);
1645
+ if (item)
1646
+ leafPaints.push(item);
1647
+ }
1648
+ data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
1649
+ if (leafPaints.length && leafPaints[0].image)
1650
+ hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
1651
+ if (attrName === 'fill') {
1652
+ data.__pixelFill = hasOpacityPixel;
1653
+ }
1654
+ else {
1655
+ data.__pixelStroke = hasOpacityPixel;
1656
+ }
1657
+ }
1658
+ function getLeafPaint(attrName, paint, ui) {
1659
+ if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
1660
+ return undefined;
1661
+ const { boxBounds } = ui.__layout;
1662
+ switch (paint.type) {
1663
+ case 'solid':
1664
+ let { type, blendMode, color, opacity } = paint;
1665
+ return { type, blendMode, style: ColorConvert.string(color, opacity) };
1666
+ case 'image':
1667
+ return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1668
+ case 'linear':
1669
+ return PaintGradient.linearGradient(paint, boxBounds);
1670
+ case 'radial':
1671
+ return PaintGradient.radialGradient(paint, boxBounds);
1672
+ case 'angular':
1673
+ return PaintGradient.conicGradient(paint, boxBounds);
1674
+ default:
1675
+ return paint.r ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
1676
+ }
1677
+ }
1678
+
1679
+ const PaintModule = {
1680
+ compute,
1681
+ fill,
1682
+ fills,
1683
+ fillText,
1684
+ stroke,
1685
+ strokes,
1686
+ strokeText,
1687
+ drawTextStroke,
1688
+ shape
1689
+ };
1690
+
1691
+ let origin = {};
1692
+ const { get: get$4, rotateOfOuter: rotateOfOuter$2, translate: translate$1, scaleOfOuter: scaleOfOuter$2, scale: scaleHelper, rotate } = MatrixHelper;
1693
+ function fillOrFitMode(data, mode, box, width, height, rotation) {
1694
+ const transform = get$4();
1695
+ const swap = rotation && rotation !== 180;
1696
+ const sw = box.width / (swap ? height : width);
1697
+ const sh = box.height / (swap ? width : height);
1698
+ const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1699
+ const x = box.x + (box.width - width * scale) / 2;
1700
+ const y = box.y + (box.height - height * scale) / 2;
1701
+ translate$1(transform, x, y);
1702
+ scaleHelper(transform, scale);
1703
+ if (rotation)
1704
+ rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
1705
+ data.scaleX = data.scaleY = scale;
1706
+ data.transform = transform;
1707
+ }
1708
+ function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
1709
+ const transform = get$4();
1710
+ translate$1(transform, box.x, box.y);
1711
+ if (x || y)
1712
+ translate$1(transform, x, y);
1713
+ if (scaleX) {
1714
+ scaleHelper(transform, scaleX, scaleY);
1715
+ data.scaleX = transform.a;
1716
+ data.scaleY = transform.d;
1717
+ }
1718
+ if (rotation)
1719
+ rotate(transform, rotation);
1720
+ data.transform = transform;
1721
+ }
1722
+ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation) {
1723
+ const transform = get$4();
1724
+ if (rotation) {
1725
+ rotate(transform, rotation);
1726
+ switch (rotation) {
1727
+ case 90:
1728
+ translate$1(transform, height, 0);
1729
+ break;
1730
+ case 180:
1731
+ translate$1(transform, width, height);
1732
+ break;
1733
+ case 270:
1734
+ translate$1(transform, 0, width);
1735
+ break;
1736
+ }
1737
+ }
1738
+ origin.x = box.x;
1739
+ origin.y = box.y;
1740
+ if (x || y)
1741
+ origin.x += x, origin.y += y;
1742
+ translate$1(transform, origin.x, origin.y);
1743
+ if (scaleX) {
1744
+ scaleOfOuter$2(transform, origin, scaleX, scaleY);
1745
+ data.scaleX = scaleX;
1746
+ data.scaleY = scaleY;
1747
+ }
1748
+ data.transform = transform;
1749
+ }
1750
+
1751
+ const { get: get$3, translate } = MatrixHelper;
1752
+ function createData(leafPaint, image, paint, box) {
1753
+ let { width, height } = image;
1754
+ const { opacity, mode, offset, scale, size, rotation, blendMode, repeat } = paint;
1755
+ const sameBox = box.width === width && box.height === height;
1756
+ if (blendMode)
1757
+ leafPaint.blendMode = blendMode;
1758
+ const data = leafPaint.data = { mode };
1759
+ let x, y, scaleX, scaleY;
1760
+ if (offset)
1761
+ x = offset.x, y = offset.y;
1762
+ if (size) {
1763
+ scaleX = (typeof size === 'number' ? size : size.width) / width;
1764
+ scaleY = (typeof size === 'number' ? size : size.height) / height;
1765
+ }
1766
+ else if (scale) {
1767
+ scaleX = typeof scale === 'number' ? scale : scale.x;
1768
+ scaleY = typeof scale === 'number' ? scale : scale.y;
1769
+ }
1770
+ switch (mode) {
1771
+ case 'strench':
1772
+ if (!sameBox)
1773
+ width = box.width, height = box.height;
1774
+ if (box.x || box.y) {
1775
+ data.transform = get$3();
1776
+ translate(data.transform, box.x, box.y);
1777
+ }
1778
+ break;
1779
+ case 'clip':
1780
+ if (offset || scaleX || rotation)
1781
+ clipMode(data, box, x, y, scaleX, scaleY, rotation);
1782
+ break;
1783
+ case 'repeat':
1784
+ if (!sameBox || scaleX || rotation)
1785
+ repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation);
1786
+ if (!repeat)
1787
+ data.repeat = 'repeat';
1788
+ break;
1789
+ case 'fit':
1790
+ case 'cover':
1791
+ default:
1792
+ if (!sameBox || rotation)
1793
+ fillOrFitMode(data, mode, box, width, height, rotation);
1794
+ }
1795
+ data.width = width;
1796
+ data.height = height;
1797
+ if (opacity)
1798
+ data.opacity = opacity;
1799
+ if (repeat)
1800
+ data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
1801
+ }
1802
+
1803
+ let cache, box = new Bounds();
1804
+ const { isSame } = BoundsHelper;
1805
+ function image(ui, attrName, paint, boxBounds, firstUse) {
1806
+ let leafPaint, event;
1807
+ const image = ImageManager.get(paint);
1808
+ if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1809
+ leafPaint = cache.leafPaint;
1810
+ }
1811
+ else {
1812
+ leafPaint = { type: paint.type };
1813
+ leafPaint.image = image;
1814
+ cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
1815
+ }
1816
+ if (firstUse || image.loading)
1817
+ event = { image, attrName, attrValue: paint };
1818
+ if (image.ready) {
1819
+ checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1820
+ if (firstUse) {
1821
+ onLoad(ui, event);
1822
+ onLoadSuccess(ui, event);
1823
+ }
1824
+ }
1825
+ else if (image.error) {
1826
+ if (firstUse)
1827
+ onLoadError(ui, event, image.error);
1828
+ }
1829
+ else {
1830
+ if (firstUse)
1831
+ onLoad(ui, event);
1832
+ leafPaint.loadId = image.load(() => {
1833
+ if (!ui.destroyed) {
1834
+ if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds))
1835
+ ui.forceUpdate('surface');
1836
+ onLoadSuccess(ui, event);
1837
+ }
1838
+ leafPaint.loadId = null;
1839
+ }, (error) => {
1840
+ onLoadError(ui, event, error);
1841
+ leafPaint.loadId = null;
1842
+ });
1843
+ }
1844
+ return leafPaint;
1845
+ }
1846
+ function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1847
+ if (attrName === 'fill' && !ui.__.__naturalWidth) {
1848
+ const data = ui.__;
1849
+ data.__naturalWidth = image.width;
1850
+ data.__naturalHeight = image.height;
1851
+ if (data.__autoWidth || data.__autoHeight) {
1852
+ ui.forceUpdate('width');
1853
+ if (ui.__proxyData) {
1854
+ ui.setProxyAttr('width', data.width);
1855
+ ui.setProxyAttr('height', data.height);
1856
+ }
1857
+ return false;
1858
+ }
1859
+ }
1860
+ if (!leafPaint.data)
1861
+ createData(leafPaint, image, paint, boxBounds);
1862
+ return true;
1863
+ }
1864
+ function onLoad(ui, event) {
1865
+ emit(ui, ImageEvent.LOAD, event);
1866
+ }
1867
+ function onLoadSuccess(ui, event) {
1868
+ emit(ui, ImageEvent.LOADED, event);
1869
+ }
1870
+ function onLoadError(ui, event, error) {
1871
+ event.error = error;
1872
+ ui.forceUpdate('surface');
1873
+ emit(ui, ImageEvent.ERROR, event);
1874
+ }
1875
+ function emit(ui, type, data) {
1876
+ if (ui.hasEvent(type))
1877
+ ui.emitEvent(new ImageEvent(type, data));
1878
+ }
1879
+
1880
+ const { get: get$2, scale, copy: copy$1 } = MatrixHelper;
1881
+ const { round, abs: abs$1 } = Math;
1882
+ function createPattern(ui, paint, pixelRatio) {
1883
+ let { scaleX, scaleY } = ui.__world;
1884
+ const id = scaleX + '-' + scaleY;
1885
+ if (paint.patternId !== id && !ui.destroyed) {
1886
+ scaleX = abs$1(scaleX);
1887
+ scaleY = abs$1(scaleY);
1888
+ const { image, data } = paint;
1889
+ let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
1890
+ if (sx) {
1891
+ imageMatrix = get$2();
1892
+ copy$1(imageMatrix, transform);
1893
+ scale(imageMatrix, 1 / sx, 1 / sy);
1894
+ scaleX *= sx;
1895
+ scaleY *= sy;
1896
+ }
1897
+ scaleX *= pixelRatio;
1898
+ scaleY *= pixelRatio;
1899
+ width *= scaleX;
1900
+ height *= scaleY;
1901
+ const size = width * height;
1902
+ if (!repeat) {
1903
+ if (size > Platform.image.maxCacheSize)
1904
+ return false;
1905
+ }
1906
+ let maxSize = Platform.image.maxPatternSize;
1907
+ if (!image.isSVG) {
1908
+ const imageSize = image.width * image.height;
1909
+ if (maxSize > imageSize)
1910
+ maxSize = imageSize;
1911
+ }
1912
+ if (size > maxSize)
1913
+ imageScale = Math.sqrt(size / maxSize);
1914
+ if (imageScale) {
1915
+ scaleX /= imageScale;
1916
+ scaleY /= imageScale;
1917
+ width /= imageScale;
1918
+ height /= imageScale;
1919
+ }
1920
+ if (sx) {
1921
+ scaleX /= sx;
1922
+ scaleY /= sy;
1923
+ }
1924
+ if (transform || scaleX !== 1 || scaleY !== 1) {
1925
+ if (!imageMatrix) {
1926
+ imageMatrix = get$2();
1927
+ if (transform)
1928
+ copy$1(imageMatrix, transform);
1929
+ }
1930
+ scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1931
+ }
1932
+ const canvas = image.getCanvas(width < 1 ? 1 : round(width), height < 1 ? 1 : round(height), opacity);
1933
+ const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
1934
+ paint.style = pattern;
1935
+ paint.patternId = id;
1936
+ return true;
1937
+ }
1938
+ else {
1939
+ return false;
1940
+ }
1941
+ }
1942
+
1943
+ /******************************************************************************
1944
+ Copyright (c) Microsoft Corporation.
1945
+
1946
+ Permission to use, copy, modify, and/or distribute this software for any
1947
+ purpose with or without fee is hereby granted.
1948
+
1949
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1950
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1951
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1952
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1953
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1954
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1955
+ PERFORMANCE OF THIS SOFTWARE.
1956
+ ***************************************************************************** */
1957
+ /* global Reflect, Promise, SuppressedError, Symbol */
1958
+
1959
+
1960
+ function __awaiter(thisArg, _arguments, P, generator) {
1961
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1962
+ return new (P || (P = Promise))(function (resolve, reject) {
1963
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1964
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1965
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1966
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
1967
+ });
1968
+ }
1969
+
1970
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1971
+ var e = new Error(message);
1972
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1973
+ };
1974
+
1975
+ const { abs } = Math;
1976
+ function checkImage(ui, canvas, paint, allowPaint) {
1977
+ const { scaleX, scaleY } = ui.__world;
1978
+ if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
1979
+ return false;
1980
+ }
1981
+ else {
1982
+ const { data } = paint;
1983
+ if (allowPaint) {
1984
+ if (!data.repeat) {
1985
+ let { width, height } = data;
1986
+ width *= abs(scaleX) * canvas.pixelRatio;
1987
+ height *= abs(scaleY) * canvas.pixelRatio;
1988
+ if (data.scaleX) {
1989
+ width *= data.scaleX;
1990
+ height *= data.scaleY;
1991
+ }
1992
+ allowPaint = width * height > Platform.image.maxCacheSize;
1993
+ }
1994
+ else {
1995
+ allowPaint = false;
1996
+ }
1997
+ }
1998
+ if (allowPaint) {
1999
+ canvas.save();
2000
+ canvas.clip();
2001
+ if (paint.blendMode)
2002
+ canvas.blendMode = paint.blendMode;
2003
+ if (data.opacity)
2004
+ canvas.opacity *= data.opacity;
2005
+ if (data.transform)
2006
+ canvas.transform(data.transform);
2007
+ canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
2008
+ canvas.restore();
2009
+ return true;
2010
+ }
2011
+ else {
2012
+ if (!paint.style || Export.running) {
2013
+ createPattern(ui, paint, canvas.pixelRatio);
2014
+ }
2015
+ else {
2016
+ if (!paint.patternTask) {
2017
+ paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
2018
+ paint.patternTask = null;
2019
+ if (canvas.bounds.hit(ui.__world))
2020
+ createPattern(ui, paint, canvas.pixelRatio);
2021
+ ui.forceUpdate('surface');
2022
+ }), 300);
2023
+ }
2024
+ }
2025
+ return false;
2026
+ }
2027
+ }
2028
+ }
2029
+
2030
+ function recycleImage(attrName, data) {
2031
+ const paints = data['_' + attrName];
2032
+ if (paints instanceof Array) {
2033
+ let image, recycleMap, input, url;
2034
+ for (let i = 0, len = paints.length; i < len; i++) {
2035
+ image = paints[i].image;
2036
+ url = image && image.url;
2037
+ if (url) {
2038
+ if (!recycleMap)
2039
+ recycleMap = {};
2040
+ recycleMap[url] = true;
2041
+ ImageManager.recycle(image);
2042
+ if (image.loading) {
2043
+ if (!input) {
2044
+ input = (data.__input && data.__input[attrName]) || [];
2045
+ if (!(input instanceof Array))
2046
+ input = [input];
2047
+ }
2048
+ image.unload(paints[i].loadId, !input.some((item) => item.url === url));
2049
+ }
2050
+ }
2051
+ }
2052
+ return recycleMap;
2053
+ }
2054
+ return null;
2055
+ }
2056
+
2057
+ const PaintImageModule = {
2058
+ image,
2059
+ createData,
2060
+ fillOrFitMode,
2061
+ clipMode,
2062
+ repeatMode,
2063
+ createPattern,
2064
+ checkImage,
2065
+ recycleImage
2066
+ };
2067
+
2068
+ const defaultFrom$2 = { x: 0.5, y: 0 };
2069
+ const defaultTo$2 = { x: 0.5, y: 1 };
2070
+ function linearGradient(paint, box) {
2071
+ let { from, to, type, blendMode, opacity } = paint;
2072
+ from || (from = defaultFrom$2);
2073
+ to || (to = defaultTo$2);
2074
+ const style = Platform.canvas.createLinearGradient(box.x + from.x * box.width, box.y + from.y * box.height, box.x + to.x * box.width, box.y + to.y * box.height);
2075
+ applyStops(style, paint.stops, opacity);
2076
+ const data = { type, style };
2077
+ if (blendMode)
2078
+ data.blendMode = blendMode;
2079
+ return data;
2080
+ }
2081
+ function applyStops(gradient, stops, opacity) {
2082
+ let stop;
2083
+ for (let i = 0, len = stops.length; i < len; i++) {
2084
+ stop = stops[i];
2085
+ gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
2086
+ }
2087
+ }
2088
+
2089
+ const { set: set$1, getAngle: getAngle$1, getDistance: getDistance$1 } = PointHelper;
2090
+ const { get: get$1, rotateOfOuter: rotateOfOuter$1, scaleOfOuter: scaleOfOuter$1 } = MatrixHelper;
2091
+ const defaultFrom$1 = { x: 0.5, y: 0.5 };
2092
+ const defaultTo$1 = { x: 0.5, y: 1 };
2093
+ const realFrom$1 = {};
2094
+ const realTo$1 = {};
2095
+ function radialGradient(paint, box) {
2096
+ let { from, to, type, opacity, blendMode, stretch } = paint;
2097
+ from || (from = defaultFrom$1);
2098
+ to || (to = defaultTo$1);
2099
+ const { x, y, width, height } = box;
2100
+ set$1(realFrom$1, x + from.x * width, y + from.y * height);
2101
+ set$1(realTo$1, x + to.x * width, y + to.y * height);
2102
+ let transform;
2103
+ if (width !== height || stretch) {
2104
+ transform = get$1();
2105
+ scaleOfOuter$1(transform, realFrom$1, width / height * (stretch || 1), 1);
2106
+ rotateOfOuter$1(transform, realFrom$1, getAngle$1(realFrom$1, realTo$1) + 90);
2107
+ }
2108
+ const style = Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
2109
+ applyStops(style, paint.stops, opacity);
2110
+ const data = { type, style, transform };
2111
+ if (blendMode)
2112
+ data.blendMode = blendMode;
2113
+ return data;
2114
+ }
2115
+
2116
+ const { set, getAngle, getDistance } = PointHelper;
2117
+ const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
2118
+ const defaultFrom = { x: 0.5, y: 0.5 };
2119
+ const defaultTo = { x: 0.5, y: 1 };
2120
+ const realFrom = {};
2121
+ const realTo = {};
2122
+ function conicGradient(paint, box) {
2123
+ let { from, to, type, opacity, blendMode, stretch } = paint;
2124
+ from || (from = defaultFrom);
2125
+ to || (to = defaultTo);
2126
+ const { x, y, width, height } = box;
2127
+ set(realFrom, x + from.x * width, y + from.y * height);
2128
+ set(realTo, x + to.x * width, y + to.y * height);
2129
+ const transform = get();
2130
+ const angle = getAngle(realFrom, realTo);
2131
+ if (Platform.conicGradientRotate90) {
2132
+ scaleOfOuter(transform, realFrom, width / height * (stretch || 1), 1);
2133
+ rotateOfOuter(transform, realFrom, angle + 90);
2134
+ }
2135
+ else {
2136
+ scaleOfOuter(transform, realFrom, 1, width / height * (stretch || 1));
2137
+ rotateOfOuter(transform, realFrom, angle);
2138
+ }
2139
+ const style = Platform.conicGradientSupport ? Platform.canvas.createConicGradient(0, realFrom.x, realFrom.y) : Platform.canvas.createRadialGradient(realFrom.x, realFrom.y, 0, realFrom.x, realFrom.y, getDistance(realFrom, realTo));
2140
+ applyStops(style, paint.stops, opacity);
2141
+ const data = { type, style, transform };
2142
+ if (blendMode)
2143
+ data.blendMode = blendMode;
2144
+ return data;
2145
+ }
2146
+
2147
+ const PaintGradientModule = {
2148
+ linearGradient,
2149
+ radialGradient,
2150
+ conicGradient
2151
+ };
2152
+
2153
+ const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
2154
+ const tempBounds = {};
2155
+ const offsetOutBounds$1 = {};
2156
+ function shadow(ui, current, shape) {
2157
+ let copyBounds, spreadScale;
2158
+ const { __nowWorld: nowWorld, __layout } = ui;
2159
+ const { shadow } = ui.__;
2160
+ const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
2161
+ const other = current.getSameCanvas();
2162
+ const end = shadow.length - 1;
2163
+ toOffsetOutBounds$1(bounds, offsetOutBounds$1);
2164
+ shadow.forEach((item, index) => {
2165
+ other.setWorldShadow((offsetOutBounds$1.offsetX + item.x * scaleX), (offsetOutBounds$1.offsetY + item.y * scaleY), item.blur * scaleX, item.color);
2166
+ spreadScale = item.spread ? 1 + item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) : 0;
2167
+ drawWorldShadow(other, offsetOutBounds$1, spreadScale, shape);
2168
+ copyBounds = bounds;
2169
+ if (item.box) {
2170
+ other.restore();
2171
+ other.save();
2172
+ if (worldCanvas) {
2173
+ other.copyWorld(other, bounds, nowWorld, 'copy');
2174
+ copyBounds = nowWorld;
2175
+ }
2176
+ worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
2177
+ }
2178
+ if (ui.__worldFlipped) {
2179
+ current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
2180
+ }
2181
+ else {
2182
+ current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
2183
+ }
2184
+ if (end && index < end)
2185
+ other.clearWorld(copyBounds, true);
2186
+ });
2187
+ other.recycle(copyBounds);
2188
+ }
2189
+ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
2190
+ const { bounds, shapeBounds } = shape;
2191
+ if (Platform.fullImageShadow) {
2192
+ copy(tempBounds, canvas.bounds);
2193
+ tempBounds.x += (outBounds.x - shapeBounds.x);
2194
+ tempBounds.y += (outBounds.y - shapeBounds.y);
2195
+ if (spreadScale) {
2196
+ const { matrix } = shape;
2197
+ tempBounds.x -= (bounds.x + (matrix ? matrix.e : 0) + bounds.width / 2) * (spreadScale - 1);
2198
+ tempBounds.y -= (bounds.y + (matrix ? matrix.f : 0) + bounds.height / 2) * (spreadScale - 1);
2199
+ tempBounds.width *= spreadScale;
2200
+ tempBounds.height *= spreadScale;
2201
+ }
2202
+ canvas.copyWorld(shape.canvas, canvas.bounds, tempBounds);
2203
+ }
2204
+ else {
2205
+ if (spreadScale) {
2206
+ copy(tempBounds, outBounds);
2207
+ tempBounds.x -= (outBounds.width / 2) * (spreadScale - 1);
2208
+ tempBounds.y -= (outBounds.height / 2) * (spreadScale - 1);
2209
+ tempBounds.width *= spreadScale;
2210
+ tempBounds.height *= spreadScale;
2211
+ }
2212
+ canvas.copyWorld(shape.canvas, shapeBounds, spreadScale ? tempBounds : outBounds);
2213
+ }
2214
+ }
2215
+
2216
+ const { toOffsetOutBounds } = BoundsHelper;
2217
+ const offsetOutBounds = {};
2218
+ function innerShadow(ui, current, shape) {
2219
+ let copyBounds, spreadScale;
2220
+ const { __nowWorld: nowWorld, __layout: __layout } = ui;
2221
+ const { innerShadow } = ui.__;
2222
+ const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
2223
+ const other = current.getSameCanvas();
2224
+ const end = innerShadow.length - 1;
2225
+ toOffsetOutBounds(bounds, offsetOutBounds);
2226
+ innerShadow.forEach((item, index) => {
2227
+ other.save();
2228
+ other.setWorldShadow((offsetOutBounds.offsetX + item.x * scaleX), (offsetOutBounds.offsetY + item.y * scaleY), item.blur * scaleX);
2229
+ spreadScale = item.spread ? 1 - item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) : 0;
2230
+ drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
2231
+ other.restore();
2232
+ if (worldCanvas) {
2233
+ other.copyWorld(other, bounds, nowWorld, 'copy');
2234
+ other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
2235
+ copyBounds = nowWorld;
2236
+ }
2237
+ else {
2238
+ other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
2239
+ copyBounds = bounds;
2240
+ }
2241
+ other.fillWorld(copyBounds, item.color, 'source-in');
2242
+ if (ui.__worldFlipped) {
2243
+ current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
2244
+ }
2245
+ else {
2246
+ current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
2247
+ }
2248
+ if (end && index < end)
2249
+ other.clearWorld(copyBounds, true);
2250
+ });
2251
+ other.recycle(copyBounds);
2252
+ }
2253
+
2254
+ function blur(ui, current, origin) {
2255
+ const { blur } = ui.__;
2256
+ origin.setWorldBlur(blur * ui.__world.a);
2257
+ origin.copyWorldToInner(current, ui.__world, ui.__layout.renderBounds);
2258
+ origin.filter = 'none';
2259
+ }
2260
+
2261
+ function backgroundBlur(_ui, _current, _shape) {
2262
+ }
2263
+
2264
+ const EffectModule = {
2265
+ shadow,
2266
+ innerShadow,
2267
+ blur,
2268
+ backgroundBlur
2269
+ };
2270
+
2271
+ const { excludeRenderBounds } = LeafBoundsHelper;
2272
+ Group.prototype.__renderMask = function (canvas, options) {
2273
+ let child, maskCanvas, contentCanvas, maskOpacity, currentMask;
2274
+ const { children } = this;
2275
+ for (let i = 0, len = children.length; i < len; i++) {
2276
+ child = children[i];
2277
+ if (child.__.mask) {
2278
+ if (currentMask) {
2279
+ maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
2280
+ maskCanvas = contentCanvas = null;
2281
+ }
2282
+ if (child.__.maskType === 'path') {
2283
+ if (child.opacity < 1) {
2284
+ currentMask = 'opacity-path';
2285
+ maskOpacity = child.opacity;
2286
+ if (!contentCanvas)
2287
+ contentCanvas = getCanvas(canvas);
2288
+ }
2289
+ else {
2290
+ currentMask = 'path';
2291
+ canvas.save();
2292
+ }
2293
+ child.__clip(contentCanvas || canvas, options);
2294
+ }
2295
+ else {
2296
+ currentMask = 'alpha';
2297
+ if (!maskCanvas)
2298
+ maskCanvas = getCanvas(canvas);
2299
+ if (!contentCanvas)
2300
+ contentCanvas = getCanvas(canvas);
2301
+ child.__render(maskCanvas, options);
2302
+ }
2303
+ if (child.__.maskType !== 'clipping')
2304
+ continue;
2305
+ }
2306
+ if (excludeRenderBounds(child, options))
2307
+ continue;
2308
+ child.__render(contentCanvas || canvas, options);
2309
+ }
2310
+ maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
2311
+ };
2312
+ function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
2313
+ switch (maskMode) {
2314
+ case 'alpha':
2315
+ usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
2316
+ break;
2317
+ case 'opacity-path':
2318
+ copyContent(leaf, canvas, contentCanvas, maskOpacity);
2319
+ break;
2320
+ case 'path':
2321
+ canvas.restore();
2322
+ }
2323
+ }
2324
+ function getCanvas(canvas) {
2325
+ return canvas.getSameCanvas(false, true);
2326
+ }
2327
+ function usePixelMask(leaf, canvas, content, mask) {
2328
+ const realBounds = leaf.__nowWorld;
2329
+ content.resetTransform();
2330
+ content.opacity = 1;
2331
+ content.useMask(mask, realBounds);
2332
+ mask.recycle(realBounds);
2333
+ copyContent(leaf, canvas, content, 1);
2334
+ }
2335
+ function copyContent(leaf, canvas, content, maskOpacity) {
2336
+ const realBounds = leaf.__nowWorld;
2337
+ canvas.resetTransform();
2338
+ canvas.opacity = maskOpacity;
2339
+ canvas.copyWorld(content, realBounds);
2340
+ content.recycle(realBounds);
2341
+ }
2342
+
2343
+ const money = '¥¥$€££¢¢';
2344
+ const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
2345
+ const langBefore = '《(「〈『〖【〔{┌<‘“=' + money;
2346
+ const langAfter = '》)」〉』〗】〕}┐>’”!?,、。:;‰';
2347
+ const langSymbol = '≮≯≈≠=…';
2348
+ const langBreak$1 = '—/~|┆·';
2349
+ const beforeChar = '{[(<\'"' + langBefore;
2350
+ const afterChar = '>)]}%!?,.:;\'"' + langAfter;
2351
+ const symbolChar = afterChar + '_#~&*+\\=|' + langSymbol;
2352
+ const breakChar = '- ' + langBreak$1;
2353
+ const cjkRangeList = [
2354
+ [0x4E00, 0x9FFF],
2355
+ [0x3400, 0x4DBF],
2356
+ [0x20000, 0x2A6DF],
2357
+ [0x2A700, 0x2B73F],
2358
+ [0x2B740, 0x2B81F],
2359
+ [0x2B820, 0x2CEAF],
2360
+ [0x2CEB0, 0x2EBEF],
2361
+ [0x30000, 0x3134F],
2362
+ [0x31350, 0x323AF],
2363
+ [0x2E80, 0x2EFF],
2364
+ [0x2F00, 0x2FDF],
2365
+ [0x2FF0, 0x2FFF],
2366
+ [0x3000, 0x303F],
2367
+ [0x31C0, 0x31EF],
2368
+ [0x3200, 0x32FF],
2369
+ [0x3300, 0x33FF],
2370
+ [0xF900, 0xFAFF],
2371
+ [0xFE30, 0xFE4F],
2372
+ [0x1F200, 0x1F2FF],
2373
+ [0x2F800, 0x2FA1F],
2374
+ ];
2375
+ const cjkReg = new RegExp(cjkRangeList.map(([start, end]) => `[\\u${start.toString(16)}-\\u${end.toString(16)}]`).join('|'));
2376
+ function mapChar(str) {
2377
+ const map = {};
2378
+ str.split('').forEach(char => map[char] = true);
2379
+ return map;
2380
+ }
2381
+ const letterMap = mapChar(letter);
2382
+ const beforeMap = mapChar(beforeChar);
2383
+ const afterMap = mapChar(afterChar);
2384
+ const symbolMap = mapChar(symbolChar);
2385
+ const breakMap = mapChar(breakChar);
2386
+ var CharType;
2387
+ (function (CharType) {
2388
+ CharType[CharType["Letter"] = 0] = "Letter";
2389
+ CharType[CharType["Single"] = 1] = "Single";
2390
+ CharType[CharType["Before"] = 2] = "Before";
2391
+ CharType[CharType["After"] = 3] = "After";
2392
+ CharType[CharType["Symbol"] = 4] = "Symbol";
2393
+ CharType[CharType["Break"] = 5] = "Break";
2394
+ })(CharType || (CharType = {}));
2395
+ const { Letter: Letter$1, Single: Single$1, Before: Before$1, After: After$1, Symbol: Symbol$1, Break: Break$1 } = CharType;
2396
+ function getCharType(char) {
2397
+ if (letterMap[char]) {
2398
+ return Letter$1;
2399
+ }
2400
+ else if (breakMap[char]) {
2401
+ return Break$1;
2402
+ }
2403
+ else if (beforeMap[char]) {
2404
+ return Before$1;
2405
+ }
2406
+ else if (afterMap[char]) {
2407
+ return After$1;
2408
+ }
2409
+ else if (symbolMap[char]) {
2410
+ return Symbol$1;
2411
+ }
2412
+ else if (cjkReg.test(char)) {
2413
+ return Single$1;
2414
+ }
2415
+ else {
2416
+ return Letter$1;
2417
+ }
2418
+ }
2419
+
2420
+ const TextRowHelper = {
2421
+ trimRight(row) {
2422
+ const { words } = row;
2423
+ let trimRight = 0, len = words.length, char;
2424
+ for (let i = len - 1; i > -1; i--) {
2425
+ char = words[i].data[0];
2426
+ if (char.char === ' ') {
2427
+ trimRight++;
2428
+ row.width -= char.width;
2429
+ }
2430
+ else {
2431
+ break;
2432
+ }
2433
+ }
2434
+ if (trimRight)
2435
+ words.splice(len - trimRight, trimRight);
2436
+ }
2437
+ };
2438
+
2439
+ function getTextCase(char, textCase, firstChar) {
2440
+ switch (textCase) {
2441
+ case 'title':
2442
+ return firstChar ? char.toUpperCase() : char;
2443
+ case 'upper':
2444
+ return char.toUpperCase();
2445
+ case 'lower':
2446
+ return char.toLowerCase();
2447
+ default:
2448
+ return char;
2449
+ }
2450
+ }
2451
+
2452
+ const { trimRight } = TextRowHelper;
2453
+ const { Letter, Single, Before, After, Symbol, Break } = CharType;
2454
+ let word, row, wordWidth, rowWidth, realWidth;
2455
+ let char, charWidth, startCharSize, charSize, charType, lastCharType, langBreak, afterBreak, paraStart;
2456
+ let textDrawData, rows = [], bounds;
2457
+ function createRows(drawData, content, style) {
2458
+ textDrawData = drawData;
2459
+ rows = drawData.rows;
2460
+ bounds = drawData.bounds;
2461
+ const { __letterSpacing, paraIndent, textCase } = style;
2462
+ const { canvas } = Platform;
2463
+ const { width, height } = bounds;
2464
+ const charMode = width || height || __letterSpacing || (textCase !== 'none');
2465
+ if (charMode) {
2466
+ const wrap = style.textWrap !== 'none';
2467
+ const breakAll = style.textWrap === 'break';
2468
+ paraStart = true;
2469
+ lastCharType = null;
2470
+ startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
2471
+ word = { data: [] }, row = { words: [] };
2472
+ for (let i = 0, len = content.length; i < len; i++) {
2473
+ char = content[i];
2474
+ if (char === '\n') {
2475
+ if (wordWidth)
2476
+ addWord();
2477
+ row.paraEnd = true;
2478
+ addRow();
2479
+ paraStart = true;
2480
+ }
2481
+ else {
2482
+ charType = getCharType(char);
2483
+ if (charType === Letter && textCase !== 'none')
2484
+ char = getTextCase(char, textCase, !wordWidth);
2485
+ charWidth = canvas.measureText(char).width;
2486
+ if (__letterSpacing) {
2487
+ if (__letterSpacing < 0)
2488
+ charSize = charWidth;
2489
+ charWidth += __letterSpacing;
2490
+ }
2491
+ langBreak = (charType === Single && (lastCharType === Single || lastCharType === Letter)) || (lastCharType === Single && charType !== After);
2492
+ afterBreak = ((charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After));
2493
+ realWidth = paraStart && paraIndent ? width - paraIndent : width;
2494
+ if (wrap && (width && rowWidth + wordWidth + charWidth > realWidth)) {
2495
+ if (breakAll) {
2496
+ if (wordWidth)
2497
+ addWord();
2498
+ addRow();
2499
+ }
2500
+ else {
2501
+ if (!afterBreak)
2502
+ afterBreak = charType === Letter && lastCharType == After;
2503
+ if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
2504
+ if (wordWidth)
2505
+ addWord();
2506
+ addRow();
2507
+ }
2508
+ else {
2509
+ addRow();
2510
+ }
2511
+ }
2512
+ }
2513
+ if (char === ' ' && paraStart !== true && (rowWidth + wordWidth) === 0) ;
2514
+ else {
2515
+ if (charType === Break) {
2516
+ if (char === ' ' && wordWidth)
2517
+ addWord();
2518
+ addChar(char, charWidth);
2519
+ addWord();
2520
+ }
2521
+ else if (langBreak || afterBreak) {
2522
+ if (wordWidth)
2523
+ addWord();
2524
+ addChar(char, charWidth);
2525
+ }
2526
+ else {
2527
+ addChar(char, charWidth);
2528
+ }
2529
+ }
2530
+ lastCharType = charType;
2531
+ }
2532
+ }
2533
+ if (wordWidth)
2534
+ addWord();
2535
+ if (rowWidth)
2536
+ addRow();
2537
+ rows.length > 0 && (rows[rows.length - 1].paraEnd = true);
2538
+ }
2539
+ else {
2540
+ content.split('\n').forEach(content => {
2541
+ textDrawData.paraNumber++;
2542
+ rows.push({ x: paraIndent || 0, text: content, width: canvas.measureText(content).width, paraStart: true });
2543
+ });
2544
+ }
2545
+ }
2546
+ function addChar(char, width) {
2547
+ if (charSize && !startCharSize)
2548
+ startCharSize = charSize;
2549
+ word.data.push({ char, width });
2550
+ wordWidth += width;
2551
+ }
2552
+ function addWord() {
2553
+ rowWidth += wordWidth;
2554
+ word.width = wordWidth;
2555
+ row.words.push(word);
2556
+ word = { data: [] };
2557
+ wordWidth = 0;
2558
+ }
2559
+ function addRow() {
2560
+ if (paraStart) {
2561
+ textDrawData.paraNumber++;
2562
+ row.paraStart = true;
2563
+ paraStart = false;
2564
+ }
2565
+ if (charSize) {
2566
+ row.startCharSize = startCharSize;
2567
+ row.endCharSize = charSize;
2568
+ startCharSize = 0;
2569
+ }
2570
+ row.width = rowWidth;
2571
+ if (bounds.width)
2572
+ trimRight(row);
2573
+ rows.push(row);
2574
+ row = { words: [] };
2575
+ rowWidth = 0;
2576
+ }
2577
+
2578
+ const CharMode = 0;
2579
+ const WordMode = 1;
2580
+ const TextMode = 2;
2581
+ function layoutChar(drawData, style, width, _height) {
2582
+ const { rows } = drawData;
2583
+ const { textAlign, paraIndent, letterSpacing } = style;
2584
+ let charX, addWordWidth, indentWidth, mode, wordChar;
2585
+ rows.forEach(row => {
2586
+ if (row.words) {
2587
+ indentWidth = paraIndent && row.paraStart ? paraIndent : 0;
2588
+ addWordWidth = (width && textAlign === 'justify' && row.words.length > 1) ? (width - row.width - indentWidth) / (row.words.length - 1) : 0;
2589
+ mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : TextMode);
2590
+ if (row.isOverflow && !letterSpacing)
2591
+ row.textMode = true;
2592
+ if (mode === TextMode) {
2593
+ row.x += indentWidth;
2594
+ toTextChar$1(row);
2595
+ }
2596
+ else {
2597
+ row.x += indentWidth;
2598
+ charX = row.x;
2599
+ row.data = [];
2600
+ row.words.forEach(word => {
2601
+ if (mode === WordMode) {
2602
+ wordChar = { char: '', x: charX };
2603
+ charX = toWordChar(word.data, charX, wordChar);
2604
+ if (wordChar.char !== ' ')
2605
+ row.data.push(wordChar);
2606
+ }
2607
+ else {
2608
+ charX = toChar(word.data, charX, row.data);
2609
+ }
2610
+ if (!row.paraEnd && addWordWidth) {
2611
+ charX += addWordWidth;
2612
+ row.width += addWordWidth;
2613
+ }
2614
+ });
2615
+ }
2616
+ row.words = null;
2617
+ }
2618
+ });
2619
+ }
2620
+ function toTextChar$1(row) {
2621
+ row.text = '';
2622
+ row.words.forEach(word => {
2623
+ word.data.forEach(char => {
2624
+ row.text += char.char;
2625
+ });
2626
+ });
2627
+ }
2628
+ function toWordChar(data, charX, wordChar) {
2629
+ data.forEach(char => {
2630
+ wordChar.char += char.char;
2631
+ charX += char.width;
2632
+ });
2633
+ return charX;
2634
+ }
2635
+ function toChar(data, charX, rowData) {
2636
+ data.forEach(char => {
2637
+ if (char.char !== ' ') {
2638
+ char.x = charX;
2639
+ rowData.push(char);
2640
+ }
2641
+ charX += char.width;
2642
+ });
2643
+ return charX;
2644
+ }
2645
+
2646
+ function layoutText(drawData, style) {
2647
+ const { rows, bounds } = drawData;
2648
+ const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing } = style;
2649
+ let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
2650
+ let starY = __baseLine;
2651
+ if (__clipText && realHeight > height) {
2652
+ realHeight = Math.max(height, __lineHeight);
2653
+ drawData.overflow = rows.length;
2654
+ }
2655
+ else {
2656
+ switch (verticalAlign) {
2657
+ case 'middle':
2658
+ y += (height - realHeight) / 2;
2659
+ break;
2660
+ case 'bottom':
2661
+ y += (height - realHeight);
2662
+ }
2663
+ }
2664
+ starY += y;
2665
+ let row, rowX, rowWidth;
2666
+ for (let i = 0, len = rows.length; i < len; i++) {
2667
+ row = rows[i];
2668
+ row.x = x;
2669
+ switch (textAlign) {
2670
+ case 'center':
2671
+ row.x += (width - row.width) / 2;
2672
+ break;
2673
+ case 'right':
2674
+ row.x += width - row.width;
2675
+ }
2676
+ if (row.paraStart && paraSpacing && i > 0)
2677
+ starY += paraSpacing;
2678
+ row.y = starY;
2679
+ starY += __lineHeight;
2680
+ if (drawData.overflow > i && starY > realHeight) {
2681
+ row.isOverflow = true;
2682
+ drawData.overflow = i + 1;
2683
+ }
2684
+ rowX = row.x;
2685
+ rowWidth = row.width;
2686
+ if (__letterSpacing < 0) {
2687
+ if (row.width < 0) {
2688
+ rowWidth = -row.width + style.fontSize + __letterSpacing;
2689
+ rowX -= rowWidth;
2690
+ rowWidth += style.fontSize;
2691
+ }
2692
+ else {
2693
+ rowWidth -= __letterSpacing;
2694
+ }
2695
+ }
2696
+ if (rowX < bounds.x)
2697
+ bounds.x = rowX;
2698
+ if (rowWidth > bounds.width)
2699
+ bounds.width = rowWidth;
2700
+ if (__clipText && width && width < rowWidth) {
2701
+ row.isOverflow = true;
2702
+ if (!drawData.overflow)
2703
+ drawData.overflow = rows.length;
2704
+ }
2705
+ }
2706
+ bounds.y = y;
2707
+ bounds.height = realHeight;
2708
+ }
2709
+
2710
+ function clipText(drawData, style) {
2711
+ const { rows, overflow } = drawData;
2712
+ let { textOverflow } = style;
2713
+ rows.splice(overflow);
2714
+ if (textOverflow !== 'hide') {
2715
+ if (textOverflow === 'ellipsis')
2716
+ textOverflow = '...';
2717
+ let char, charRight;
2718
+ const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
2719
+ const right = style.x + style.width - ellipsisWidth;
2720
+ const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
2721
+ list.forEach(row => {
2722
+ if (row.isOverflow && row.data) {
2723
+ let end = row.data.length - 1;
2724
+ for (let i = end; i > -1; i--) {
2725
+ char = row.data[i];
2726
+ charRight = char.x + char.width;
2727
+ if (i === end && charRight < right) {
2728
+ break;
2729
+ }
2730
+ else if (charRight < right && char.char !== ' ') {
2731
+ row.data.splice(i + 1);
2732
+ row.width -= char.width;
2733
+ break;
2734
+ }
2735
+ row.width -= char.width;
2736
+ }
2737
+ row.width += ellipsisWidth;
2738
+ row.data.push({ char: textOverflow, x: charRight });
2739
+ if (row.textMode)
2740
+ toTextChar(row);
2741
+ }
2742
+ });
2743
+ }
2744
+ }
2745
+ function toTextChar(row) {
2746
+ row.text = '';
2747
+ row.data.forEach(char => {
2748
+ row.text += char.char;
2749
+ });
2750
+ row.data = null;
2751
+ }
2752
+
2753
+ function decorationText(drawData, style) {
2754
+ const { fontSize } = style;
2755
+ drawData.decorationHeight = fontSize / 11;
2756
+ switch (style.textDecoration) {
2757
+ case 'under':
2758
+ drawData.decorationY = fontSize * 0.15;
2759
+ break;
2760
+ case 'delete':
2761
+ drawData.decorationY = -fontSize * 0.35;
2762
+ }
2763
+ }
2764
+
2765
+ const { top, right, bottom, left } = Direction4;
2766
+ function getDrawData(content, style) {
2767
+ if (typeof content !== 'string')
2768
+ content = String(content);
2769
+ let x = 0, y = 0;
2770
+ let width = style.__getInput('width') || 0;
2771
+ let height = style.__getInput('height') || 0;
2772
+ const { textDecoration, __font, __padding: padding } = style;
2773
+ if (padding) {
2774
+ if (width) {
2775
+ x = padding[left];
2776
+ width -= (padding[right] + padding[left]);
2777
+ }
2778
+ if (height) {
2779
+ y = padding[top];
2780
+ height -= (padding[top] + padding[bottom]);
2781
+ }
2782
+ }
2783
+ const drawData = {
2784
+ bounds: { x, y, width, height },
2785
+ rows: [],
2786
+ paraNumber: 0,
2787
+ font: Platform.canvas.font = __font
2788
+ };
2789
+ createRows(drawData, content, style);
2790
+ if (padding)
2791
+ padAutoText(padding, drawData, style, width, height);
2792
+ layoutText(drawData, style);
2793
+ layoutChar(drawData, style, width);
2794
+ if (drawData.overflow)
2795
+ clipText(drawData, style);
2796
+ if (textDecoration !== 'none')
2797
+ decorationText(drawData, style);
2798
+ return drawData;
2799
+ }
2800
+ function padAutoText(padding, drawData, style, width, height) {
2801
+ if (!width) {
2802
+ switch (style.textAlign) {
2803
+ case 'left':
2804
+ offsetText(drawData, 'x', padding[left]);
2805
+ break;
2806
+ case 'right':
2807
+ offsetText(drawData, 'x', -padding[right]);
2808
+ }
2809
+ }
2810
+ if (!height) {
2811
+ switch (style.verticalAlign) {
2812
+ case 'top':
2813
+ offsetText(drawData, 'y', padding[top]);
2814
+ break;
2815
+ case 'bottom':
2816
+ offsetText(drawData, 'y', -padding[bottom]);
2817
+ }
2818
+ }
2819
+ }
2820
+ function offsetText(drawData, attrName, value) {
2821
+ const { bounds, rows } = drawData;
2822
+ bounds[attrName] += value;
2823
+ for (let i = 0; i < rows.length; i++)
2824
+ rows[i][attrName] += value;
2825
+ }
2826
+
2827
+ const TextConvertModule = {
2828
+ getDrawData
2829
+ };
2830
+
2831
+ function string(color, opacity) {
2832
+ if (typeof color === 'string')
2833
+ return color;
2834
+ let a = color.a === undefined ? 1 : color.a;
2835
+ if (opacity)
2836
+ a *= opacity;
2837
+ const rgb = color.r + ',' + color.g + ',' + color.b;
2838
+ return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
2839
+ }
2840
+
2841
+ const ColorConvertModule = {
2842
+ string
2843
+ };
2844
+
2845
+ const { setPoint, addPoint, toBounds } = TwoPointBoundsHelper;
2846
+ function getTrimBounds(canvas) {
2847
+ const { width, height } = canvas.view;
2848
+ const { data } = canvas.context.getImageData(0, 0, width, height);
2849
+ let x, y, pointBounds, index = 0;
2850
+ for (let i = 0; i < data.length; i += 4) {
2851
+ if (data[i + 3] !== 0) {
2852
+ x = index % width;
2853
+ y = (index - x) / width;
2854
+ pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
2855
+ }
2856
+ index++;
2857
+ }
2858
+ const bounds = new Bounds();
2859
+ toBounds(pointBounds, bounds);
2860
+ return bounds.scale(1 / canvas.pixelRatio).ceil();
2861
+ }
2862
+
2863
+ const ExportModule = {
2864
+ export(leaf, filename, options) {
2865
+ this.running = true;
2866
+ return addTask((success) => new Promise((resolve) => {
2867
+ const over = (result) => {
2868
+ success(result);
2869
+ resolve();
2870
+ this.running = false;
2871
+ };
2872
+ const { leafer } = leaf;
2873
+ if (leafer) {
2874
+ leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
2875
+ let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
2876
+ options = FileHelper.getExportOptions(options);
2877
+ const { scale, pixelRatio, slice, trim } = options;
2878
+ const screenshot = options.screenshot || leaf.isApp;
2879
+ const fill = options.fill === undefined ? ((leaf.isLeafer && screenshot) ? leaf.fill : '') : options.fill;
2880
+ const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
2881
+ if (screenshot) {
2882
+ renderBounds = screenshot === true ? (leaf.isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
2883
+ }
2884
+ else {
2885
+ const { localTransform, __world: world } = leaf;
2886
+ matrix.set(world).divide(localTransform).invert();
2887
+ scaleX = 1 / (world.scaleX / leaf.scaleX);
2888
+ scaleY = 1 / (world.scaleY / leaf.scaleY);
2889
+ renderBounds = leaf.getBounds('render', 'local');
2890
+ }
2891
+ let { x, y, width, height } = renderBounds;
2892
+ if (scale) {
2893
+ matrix.scale(scale);
2894
+ width *= scale, height *= scale;
2895
+ scaleX *= scale, scaleY *= scale;
2896
+ }
2897
+ let canvas = Creator.canvas({ width, height, pixelRatio });
2898
+ const renderOptions = { matrix: matrix.translate(-x, -y).withScale(scaleX, scaleY) };
2899
+ if (slice) {
2900
+ leaf = leafer;
2901
+ renderOptions.bounds = canvas.bounds;
2902
+ }
2903
+ canvas.save();
2904
+ leaf.__render(canvas, renderOptions);
2905
+ canvas.restore();
2906
+ if (trim) {
2907
+ trimBounds = getTrimBounds(canvas);
2908
+ const old = canvas, { width, height } = trimBounds;
2909
+ const config = { x: 0, y: 0, width, height, pixelRatio };
2910
+ canvas = Creator.canvas(config);
2911
+ canvas.copyWorld(old, trimBounds, config);
2912
+ }
2913
+ if (needFill)
2914
+ canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
2915
+ const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
2916
+ over({ data, renderBounds, trimBounds });
2917
+ }));
2918
+ }
2919
+ else {
2920
+ over({ data: false });
2921
+ }
2922
+ }));
2923
+ }
2924
+ };
2925
+ let tasker;
2926
+ function addTask(task) {
2927
+ if (!tasker)
2928
+ tasker = new TaskProcessor();
2929
+ return new Promise((resolve) => {
2930
+ tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
2931
+ });
2932
+ }
2933
+
2934
+ Object.assign(TextConvert, TextConvertModule);
2935
+ Object.assign(ColorConvert, ColorConvertModule);
2936
+ Object.assign(Paint, PaintModule);
2937
+ Object.assign(PaintImage$1, PaintImageModule);
2938
+ Object.assign(PaintGradient$1, PaintGradientModule);
2939
+ Object.assign(Effect, EffectModule);
2940
+ Object.assign(Export, ExportModule);
2941
+
2942
+ Object.assign(Creator, {
2943
+ interaction: (target, canvas, selector, options) => new Interaction(target, canvas, selector, options),
2944
+ hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
2945
+ hitCanvasManager: () => new HitCanvasManager()
2946
+ });
2947
+ useCanvas();
2948
+
2949
+ export { Interaction, Layouter, LeaferCanvas, Renderer, Selector, Watcher, useCanvas };