leafer-ui 1.0.1 → 1.0.3

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