leafer-ui 1.0.0 → 1.0.2

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