@pacem/pacem-2d 1.0.0-abel

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2750 @@
1
+ (function (pacemFoundation, pacemCore) {
2
+ 'use strict';
3
+
4
+ const TAG_MIDDLE_NAME = "2d";
5
+
6
+ function isDrawable(object) {
7
+ return !pacemCore.Utils.isNull(object) && 'stage' in object;
8
+ }
9
+ function isUiObject(object) {
10
+ return /*'transformMatrix' in object &&*/ isDrawable(object);
11
+ }
12
+ function isGradient(object) {
13
+ return 'stops' in object && pacemCore.Utils.isArray(object.stops);
14
+ }
15
+ function isLinearGradient(object) {
16
+ return isGradient(object) && 'start' in object && pacemFoundation.Point.isPoint(object.start)
17
+ && 'end' in object && pacemFoundation.Point.isPoint(object.end);
18
+ }
19
+ function isRadialGradient(object) {
20
+ return isGradient(object) && 'center' in object && pacemFoundation.Point.isPoint(object.center)
21
+ && 'radius' in object && typeof object.radius === 'number';
22
+ }
23
+ class PresentationState {
24
+ static combine(lhs, rhs, precomputedMatrix = null) {
25
+ return {
26
+ opacity: (lhs.opacity ?? 1) * (rhs.opacity ?? 1),
27
+ transformMatrix: precomputedMatrix ?? pacemFoundation.Matrix2D.multiply(rhs.transformMatrix, lhs.transformMatrix),
28
+ dashArray: lhs.dashArray ?? rhs.dashArray,
29
+ fill: lhs.fill ?? rhs.fill,
30
+ lineCap: lhs.lineCap ?? rhs.lineCap,
31
+ lineJoin: lhs.lineJoin ?? rhs.lineJoin,
32
+ lineWidth: lhs.lineWidth ?? rhs.lineWidth,
33
+ stroke: lhs.stroke ?? rhs.stroke
34
+ };
35
+ }
36
+ }
37
+ function isPresentationObject(object) {
38
+ return isUiObject(object)
39
+ && ('fill' in object
40
+ || 'transformMatrix' in object
41
+ || 'stroke' in object
42
+ || 'lineJoin' in object
43
+ || 'dashArray' in object
44
+ || 'lineWidth' in object
45
+ || 'opacity' in object
46
+ || 'lineCap' in object);
47
+ }
48
+ function isShape(object) {
49
+ return isUiObject(object) && 'pathData' in object;
50
+ }
51
+ function isGroup(object) {
52
+ return isUiObject(object) && 'childDrawables' in object && !pacemCore.Utils.isNullOrEmpty(object['childDrawables']);
53
+ }
54
+ function isText(object) {
55
+ return isUiObject(object) && 'text' in object && typeof object['text'] === 'string';
56
+ }
57
+ function isImage(object) {
58
+ return isUiObject(object) && 'src' in object && typeof object['src'] === 'string';
59
+ }
60
+ class UI2DEvent extends pacemCore.CustomUIEvent {
61
+ constructor(type, eventInit, originalEvent, transformMatrix) {
62
+ super(type, eventInit, originalEvent);
63
+ this.#transformMatrix = transformMatrix;
64
+ }
65
+ #transformMatrix;
66
+ /** Gets the screen transform matrix. */
67
+ get transformMatrix() {
68
+ return this.#transformMatrix;
69
+ }
70
+ project(pt = { x: this.screenX, y: this.screenY }) {
71
+ return pacemFoundation.Matrix2D.multiply(pt, this.#transformMatrix);
72
+ }
73
+ }
74
+ class Shape {
75
+ static empty() {
76
+ return { pathData: '', vertices: [], boundingRect: { x: 0, y: 0, width: 0, height: 0 } };
77
+ }
78
+ }
79
+ class DragEvent extends UI2DEvent {
80
+ }
81
+ class DrawableEvent extends UI2DEvent {
82
+ constructor(type, args, originalEvent, m) {
83
+ super(type, { detail: args, bubbles: true, cancelable: true }, originalEvent, m);
84
+ }
85
+ }
86
+ class StageEvent extends UI2DEvent {
87
+ constructor(type, args, originalEvent, m = args.transformMatrix) {
88
+ super(type, { detail: args, bubbles: true, cancelable: true }, originalEvent, m);
89
+ }
90
+ }
91
+
92
+ var drawing = /*#__PURE__*/Object.freeze({
93
+ __proto__: null,
94
+ DragEvent: DragEvent,
95
+ DrawableEvent: DrawableEvent,
96
+ PresentationState: PresentationState,
97
+ Shape: Shape,
98
+ StageEvent: StageEvent,
99
+ UI2DEvent: UI2DEvent,
100
+ isDrawable: isDrawable,
101
+ isGroup: isGroup,
102
+ isImage: isImage,
103
+ isLinearGradient: isLinearGradient,
104
+ isPresentationObject: isPresentationObject,
105
+ isRadialGradient: isRadialGradient,
106
+ isShape: isShape,
107
+ isText: isText,
108
+ isUiObject: isUiObject
109
+ });
110
+
111
+ var __decorate$d = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
112
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
113
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
114
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
115
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
116
+ };
117
+ //namespace Pacem.Components.Drawing {
118
+ // group [1] := align x,[3] := align y,[6] := slice
119
+ const ASPECTRATIO_PATTERN = /^\s*[xX]\s*([Mm](in|ax|id))\s*[yY]\s*([Mm](in|ax|id))(\s+(none|slice|meet))?\s*$/;
120
+ const aspectRatioPropertyConverter = {
121
+ convert: (attr) => {
122
+ const regArr = ASPECTRATIO_PATTERN.exec(attr);
123
+ if (regArr && regArr.length >= 4) {
124
+ return {
125
+ x: regArr[1].toLowerCase(),
126
+ y: regArr[3].toLowerCase(),
127
+ slice: regArr[6] === 'slice'
128
+ };
129
+ }
130
+ return 'none';
131
+ },
132
+ convertBack: (val) => {
133
+ if (pacemCore.Utils.isNull(val) || typeof val === 'string') {
134
+ return 'none';
135
+ }
136
+ return `xM${(val.x.substring(1))}YM${(val.y.substring(1))} ${(val.slice ? 'slice' : 'meet')}`;
137
+ }
138
+ };
139
+ const DEFAULT_STAGE_OPTIONS = {
140
+ panControl: true,
141
+ zoomControl: true,
142
+ panModifiers: [pacemCore.EventKeyModifier.AltKey],
143
+ zoomModifiers: [pacemCore.EventKeyModifier.AltKey],
144
+ clickModifiers: []
145
+ };
146
+ function getStageOptions(stage) {
147
+ const options = stage instanceof Pacem2DElement ? stage.options : {};
148
+ return pacemCore.Utils.extend({}, DEFAULT_STAGE_OPTIONS, options);
149
+ }
150
+ let Pacem2DElement = class Pacem2DElement extends pacemCore.Components.PacemItemsContainerElement {
151
+ constructor() {
152
+ super(...arguments);
153
+ this.#transformMatrix = pacemFoundation.Matrix2D.identity;
154
+ this.#options = DEFAULT_STAGE_OPTIONS;
155
+ this._resizeHandler = (evt) => {
156
+ this.#size = { x: evt.detail.left, y: evt.detail.top, width: evt.detail.width, height: evt.detail.height };
157
+ const adapter = this.adapter;
158
+ if (!pacemCore.Utils.isNull(adapter)) {
159
+ this._invalidateSize();
160
+ }
161
+ };
162
+ this._zoomHandler = (evt) => {
163
+ // only trusted ui interaction
164
+ if (!evt.isTrusted) {
165
+ return;
166
+ }
167
+ const opts = this.#options;
168
+ if (opts.zoomControl && pacemCore.CustomEventUtils.matchModifiers(evt, opts.zoomModifiers)) {
169
+ // prevent anything
170
+ pacemCore.avoidHandler(evt);
171
+ const zoomingOut = evt.deltaY < 0;
172
+ // center change?
173
+ const factor = .1, sign = zoomingOut ? -1 : 1, factorWSign = factor * sign, scale = 1 + factorWSign;
174
+ const stageRect = pacemCore.Utils.offsetRect(evt.currentTarget), pt = { x: evt.clientX, y: evt.clientY };
175
+ this._zoom(scale, stageRect, pt);
176
+ }
177
+ };
178
+ this._panHandler = (evt) => {
179
+ const state = this.#panningStart, actual = this._getPanPoint(evt);
180
+ if (!pacemCore.Utils.isNullOrEmpty(state && state.point) && !pacemCore.Utils.isNull(actual)) {
181
+ pacemCore.avoidHandler(evt);
182
+ const factor = state.factor, vbox = state.box, start = state.point;
183
+ this.viewbox = {
184
+ x: vbox.x - factor * (actual.x - start.x),
185
+ y: vbox.y - factor * (actual.y - start.y),
186
+ width: vbox.width,
187
+ height: vbox.height
188
+ };
189
+ }
190
+ };
191
+ this._panStartHandler = (evt) => {
192
+ const opts = this.#options;
193
+ if (!opts.panControl) {
194
+ return;
195
+ }
196
+ // only trusted ui interaction
197
+ if (!evt.isTrusted) {
198
+ return;
199
+ }
200
+ const size = this.#size, vbox = this.viewbox || { x: 0, y: 0, width: size.width, height: size.height }, start = this._getPanPoint(evt);
201
+ if (start) {
202
+ pacemCore.avoidHandler(evt);
203
+ this._stage.style.pointerEvents = 'none';
204
+ const aspectRatio = this._getActualAspectRatio();
205
+ const wBased = vbox.width / size.width, hBased = vbox.height / size.height, factor = aspectRatio.slice ? Math.min(wBased, hBased) : Math.max(wBased, hBased);
206
+ this.#panningStart = { point: start, box: vbox, factor };
207
+ }
208
+ };
209
+ this._panEndHandler = (evt) => {
210
+ this._stage.style.pointerEvents = '';
211
+ this.#panningStart = null;
212
+ };
213
+ }
214
+ get stage() {
215
+ return this._stage;
216
+ }
217
+ snapshot(bgColor, type, quality) {
218
+ const adapter = this.adapter;
219
+ if (pacemCore.Utils.isNull(adapter)) {
220
+ return Promise.resolve(null);
221
+ }
222
+ return adapter.snapshot(this, bgColor, type, quality);
223
+ }
224
+ #originalViewBox;
225
+ #transformMatrix;
226
+ get transformMatrix() {
227
+ return this.#transformMatrix;
228
+ }
229
+ _transformMatrixScale() {
230
+ const sizeObj = this.#size || pacemCore.Utils.offsetRect(this._stage);
231
+ var origVbox = this.#originalViewBox || sizeObj;
232
+ const vbox = this.viewbox || origVbox;
233
+ const aspectRatio = this.aspectRatio || 'none';
234
+ const mode = aspectRatio === 'none' ? 'stretch' : (aspectRatio.slice ? 'cover' : 'contain');
235
+ const actual = pacemFoundation.Rect.findTransform(vbox, origVbox, mode);
236
+ return actual.a;
237
+ }
238
+ validate(item) {
239
+ return item instanceof DrawableElement && /* only direct items */ pacemCore.Utils.isNull(item.parent);
240
+ }
241
+ draw(item, redraw = false) {
242
+ const adapter = this.adapter;
243
+ if (!this.disabled && !pacemCore.Utils.isNull(adapter)) {
244
+ let cancelable = new CustomEvent('predraw', { cancelable: true });
245
+ this.dispatchEvent(cancelable);
246
+ if (!cancelable.defaultPrevented) {
247
+ adapter.draw(this, item, redraw);
248
+ this.dispatchEvent(new CustomEvent('draw'));
249
+ }
250
+ }
251
+ }
252
+ _drawDebounced(item, force = false) {
253
+ if (!pacemCore.Utils.isNull(item) && isGroup(item)) {
254
+ this.draw(item, force);
255
+ }
256
+ else {
257
+ this.draw(item);
258
+ }
259
+ }
260
+ requestDraw(item, redraw = false) {
261
+ this._drawDebounced(item, redraw);
262
+ }
263
+ _buildUpDatasourceFromDOM() {
264
+ this.datasource = (this.items || []).slice();
265
+ }
266
+ #options;
267
+ #size;
268
+ _getActualAspectRatio() {
269
+ const aspectRatio = this.aspectRatio || 'none';
270
+ const alignmentX = aspectRatio === 'none' ? 'mid' : aspectRatio.x;
271
+ const alignmentY = aspectRatio === 'none' ? 'mid' : aspectRatio.y;
272
+ const slice = aspectRatio === 'none' ? false : aspectRatio.slice;
273
+ return { x: alignmentX, y: alignmentY, slice };
274
+ }
275
+ _zoomFromValue(scale) {
276
+ const sizeObj = this.#size;
277
+ if (pacemCore.Utils.isNull(sizeObj)) {
278
+ return;
279
+ }
280
+ const sizeRect = sizeObj;
281
+ const origVbox = this.#originalViewBox || sizeRect, vbox = this.viewbox || origVbox;
282
+ const aspectRatio = this.aspectRatio || 'none';
283
+ const mode = aspectRatio === 'none' ? 'stretch' : (aspectRatio.slice ? 'cover' : 'contain');
284
+ const actual = pacemFoundation.Rect.findTransform(vbox, sizeRect, mode);
285
+ const original = pacemFoundation.Rect.findTransform(origVbox, sizeRect, mode);
286
+ const actualScale = actual.a;
287
+ const origScale = original.a;
288
+ const targetScale = origScale * scale;
289
+ const incrementalInverseScale = actualScale / targetScale;
290
+ this._zoom(incrementalInverseScale);
291
+ }
292
+ _zoom(scale, stageRect, pt) {
293
+ if (pacemCore.Utils.isNull(stageRect)) {
294
+ stageRect = pacemCore.Utils.offsetRect(this._stage);
295
+ }
296
+ if (pacemCore.Utils.isNull(pt)) {
297
+ pt = { x: stageRect.x + stageRect.width * .5, y: stageRect.y + stageRect.height * .5 };
298
+ }
299
+ const sizeObj = this.#size, vbox = this.viewbox || sizeObj;
300
+ const vsize = Math.min(vbox.width, vbox.height), targetWidth = vsize * scale, targetHeight = vsize * scale;
301
+ if (targetWidth > 0 && targetHeight > 0) {
302
+ const aspectRatio = this._getActualAspectRatio();
303
+ const alignmentX = aspectRatio.x;
304
+ const alignmentY = aspectRatio.y;
305
+ const slice = aspectRatio.slice;
306
+ // offset
307
+ const vboxRatio = vbox.width / vbox.height, size = slice ? Math.max(stageRect.width, stageRect.height) : Math.min(stageRect.width, stageRect.height);
308
+ let
309
+ // to be adjusted based on aspectRatio
310
+ adjX, adjY;
311
+ switch (alignmentX) {
312
+ case 'mid':
313
+ adjX = (targetWidth - vbox.width) * (pt.x - stageRect.x - .5 * (stageRect.width - size)) / (size * vboxRatio);
314
+ break;
315
+ case 'max':
316
+ adjX = (targetWidth - vbox.width) * (pt.x - stageRect.x - (stageRect.width - size)) / (size * vboxRatio);
317
+ break;
318
+ default:
319
+ adjX = (targetWidth - vbox.width) * (pt.x - stageRect.x) / (size * vboxRatio);
320
+ break;
321
+ }
322
+ switch (alignmentY) {
323
+ case 'mid':
324
+ adjY = (targetHeight - vbox.height) * (pt.y - stageRect.y - .5 * (stageRect.height - size)) / (size * vboxRatio);
325
+ break;
326
+ case 'max':
327
+ adjY = (targetHeight - vbox.height) * (pt.y - stageRect.y - (stageRect.height - size)) / (size * vboxRatio);
328
+ break;
329
+ default:
330
+ adjY = (targetHeight - vbox.height) * (pt.y - stageRect.y) / (size * vboxRatio);
331
+ break;
332
+ }
333
+ const targetX = vbox.x - adjX, targetY = vbox.y - adjY;
334
+ this.viewbox = { x: targetX, y: targetY, width: targetWidth, height: targetHeight };
335
+ }
336
+ }
337
+ _getPanPoint(evt) {
338
+ const opts = this.#options;
339
+ if (evt instanceof MouseEvent && pacemCore.CustomEventUtils.matchModifiers(evt, opts.panModifiers)) {
340
+ return pacemCore.CustomEventUtils.getEventCoordinates(evt).page;
341
+ }
342
+ return null;
343
+ }
344
+ #panningStart;
345
+ _invalidateSize() {
346
+ this.adapter.invalidateSize(this, this.#size);
347
+ const prevTransformMatrix = this.#transformMatrix;
348
+ this.#transformMatrix = this.adapter.getTransformMatrix(this);
349
+ this.dispatchEvent(new pacemCore.PropertyChangeEvent({ propertyName: 'transformMatrix', currentValue: this.#transformMatrix, oldValue: prevTransformMatrix }));
350
+ this.zoom = this._transformMatrixScale();
351
+ this.dispatchEvent(new pacemCore.Components.ResizeEvent(this.#size));
352
+ }
353
+ viewActivatedCallback() {
354
+ super.viewActivatedCallback();
355
+ const adapter = this.adapter;
356
+ if (!pacemCore.Utils.isNull(adapter)) {
357
+ adapter.initialize(this);
358
+ this._invalidateSize();
359
+ // request draw right away
360
+ this._drawDebounced();
361
+ }
362
+ const resize = this._resize;
363
+ resize.addEventListener(pacemCore.Components.ResizeEventName, this._resizeHandler, false);
364
+ const stage = this._stage;
365
+ resize.target = stage;
366
+ const options = { capture: false, passive: true };
367
+ // zooming
368
+ stage.addEventListener('wheel', this._zoomHandler, false);
369
+ // panning
370
+ stage.addEventListener('mousedown', this._panStartHandler, false);
371
+ stage.addEventListener('touchstart', this._panStartHandler, options);
372
+ window.addEventListener('mousemove', this._panHandler, false);
373
+ window.addEventListener('mouseup', this._panEndHandler, false);
374
+ window.addEventListener('touchmove', this._panHandler, options);
375
+ window.addEventListener('touchend', this._panEndHandler, options);
376
+ }
377
+ propertyChangedCallback(name, old, val, first) {
378
+ super.propertyChangedCallback(name, old, val, first);
379
+ switch (name) {
380
+ case 'adapter':
381
+ if (!pacemCore.Utils.isNull(old)) {
382
+ old.dispose(this);
383
+ }
384
+ if (!pacemCore.Utils.isNull(val)) {
385
+ val.initialize(this);
386
+ this._invalidateSize();
387
+ this._drawDebounced();
388
+ }
389
+ break;
390
+ case 'aspectRatio':
391
+ if (!pacemCore.Utils.isNull(this.adapter)) {
392
+ this._invalidateSize();
393
+ }
394
+ break;
395
+ case 'viewbox':
396
+ if (!pacemCore.Utils.isNull(this.adapter)) {
397
+ this._invalidateSize();
398
+ }
399
+ this.#originalViewBox ??= (this.viewbox || null);
400
+ break;
401
+ case 'items':
402
+ this._buildUpDatasourceFromDOM();
403
+ break;
404
+ case 'zoom':
405
+ if (val !== this._transformMatrixScale()) {
406
+ this._zoomFromValue(val);
407
+ }
408
+ break;
409
+ case 'options':
410
+ this.#options = getStageOptions(this); // Utils.extend({}, DEFAULT_STAGE_OPTIONS, val || {});
411
+ break;
412
+ case 'disabled':
413
+ case 'datasource':
414
+ this._drawDebounced();
415
+ break;
416
+ }
417
+ }
418
+ disconnectedCallback() {
419
+ const resizer = this._resize, stage = this._stage;
420
+ if (!pacemCore.Utils.isNull(resizer)) {
421
+ resizer.removeEventListener(pacemCore.Components.ResizeEventName, this._resizeHandler, false);
422
+ }
423
+ if (!pacemCore.Utils.isNull(stage)) {
424
+ // zooming
425
+ stage.removeEventListener('wheel', this._zoomHandler, false);
426
+ // panning
427
+ stage.removeEventListener('mousedown', this._panStartHandler, false);
428
+ stage.removeEventListener('touchstart', this._panStartHandler);
429
+ window.removeEventListener('mousemove', this._panHandler, false);
430
+ window.removeEventListener('mouseup', this._panEndHandler, false);
431
+ window.removeEventListener('touchmove', this._panHandler);
432
+ window.removeEventListener('touchend', this._panEndHandler);
433
+ }
434
+ if (!pacemCore.Utils.isNull(this.adapter)) {
435
+ this.adapter.dispose(this);
436
+ }
437
+ super.disconnectedCallback();
438
+ }
439
+ };
440
+ __decorate$d([
441
+ pacemCore.Watch({ converter: pacemCore.PropertyConverters.Element })
442
+ ], Pacem2DElement.prototype, "adapter", void 0);
443
+ __decorate$d([
444
+ pacemCore.Watch({ reflectBack: true, converter: pacemCore.PropertyConverters.Rect })
445
+ ], Pacem2DElement.prototype, "viewbox", void 0);
446
+ __decorate$d([
447
+ pacemCore.Watch({ emit: false, reflectBack: true, converter: aspectRatioPropertyConverter })
448
+ ], Pacem2DElement.prototype, "aspectRatio", void 0);
449
+ __decorate$d([
450
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Json })
451
+ ], Pacem2DElement.prototype, "datasource", void 0);
452
+ __decorate$d([
453
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Json })
454
+ ], Pacem2DElement.prototype, "options", void 0);
455
+ __decorate$d([
456
+ pacemCore.Watch({ converter: pacemCore.PropertyConverters.Number })
457
+ ], Pacem2DElement.prototype, "zoom", void 0);
458
+ __decorate$d([
459
+ pacemCore.ViewChild('.' + pacemCore.PCSS + '-2d')
460
+ ], Pacem2DElement.prototype, "_stage", void 0);
461
+ __decorate$d([
462
+ pacemCore.ViewChild(pacemCore.P + '-resize')
463
+ ], Pacem2DElement.prototype, "_resize", void 0);
464
+ __decorate$d([
465
+ pacemCore.Debounce(true)
466
+ ], Pacem2DElement.prototype, "_drawDebounced", null);
467
+ Pacem2DElement = __decorate$d([
468
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME, shadow: true, template: `<${pacemCore.P}-resize watch-position="true"></${pacemCore.P}-resize><div class="${pacemCore.PCSS}-2d" part="container"></div><slot></slot>` })
469
+ ], Pacem2DElement);
470
+
471
+ var __decorate$c = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
472
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
473
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
474
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
475
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
476
+ };
477
+ class DrawableElement extends pacemCore.Components.PacemCrossItemsContainerElement {
478
+ validate(_) {
479
+ // by default no children allowed (Group will except)
480
+ return false;
481
+ }
482
+ findContainer() {
483
+ // override
484
+ return this.parent || this.stage;
485
+ }
486
+ get stage() {
487
+ return this['_scene'] = this['_scene'] || pacemCore.CustomElementUtils.findAncestorOfType(this, Pacem2DElement);
488
+ }
489
+ get parent() {
490
+ return this['_drawableParent'] = this['_drawableParent'] || pacemCore.CustomElementUtils.findAncestor(this, i => i instanceof DrawableElement);
491
+ }
492
+ disconnectedCallback() {
493
+ delete this['_scene'];
494
+ delete this['_drawableParent'];
495
+ super.disconnectedCallback();
496
+ }
497
+ propertyChangedCallback(name, old, val, first) {
498
+ super.propertyChangedCallback(name, old, val, first);
499
+ if (!first) {
500
+ switch (name) {
501
+ case 'hide':
502
+ this.stage?.draw(this);
503
+ break;
504
+ }
505
+ }
506
+ }
507
+ }
508
+ __decorate$c([
509
+ pacemCore.Watch({ emit: false, reflectBack: true, converter: pacemCore.PropertyConverters.String })
510
+ ], DrawableElement.prototype, "tag", void 0);
511
+ __decorate$c([
512
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Boolean })
513
+ ], DrawableElement.prototype, "inert", void 0);
514
+
515
+ var __decorate$b = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
516
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
517
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
518
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
519
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
520
+ };
521
+ //namespace Pacem.Components.Drawing {
522
+ const DEG2RAD = Math.PI / 180.0;
523
+ class UiElement extends DrawableElement {
524
+ #transformMatrix = pacemFoundation.Matrix2D.identity;
525
+ viewActivatedCallback() {
526
+ super.viewActivatedCallback();
527
+ this._updateTransformMatrix();
528
+ }
529
+ propertyChangedCallback(name, old, val, first) {
530
+ super.propertyChangedCallback(name, old, val, first);
531
+ if (!first) {
532
+ switch (name) {
533
+ case 'rotate':
534
+ case 'scaleX':
535
+ case 'scaleY':
536
+ case 'translateX':
537
+ case 'translateY':
538
+ this._updateTransformMatrix();
539
+ // flow down
540
+ case 'opacity':
541
+ this.stage?.draw(this);
542
+ break;
543
+ }
544
+ }
545
+ }
546
+ _updateTransformMatrix() {
547
+ let rotation = DEG2RAD * (this.rotate ?? 0), cos = Math.cos(rotation), sin = Math.sin(rotation), a = (this.scaleX ?? 1) * cos, b = -sin, c = sin, d = (this.scaleY ?? 1) * cos, e = this.translateX ?? 0, f = this.translateY ?? 0;
548
+ this.#transformMatrix = { a, b, c, d, e, f };
549
+ }
550
+ /** @internal */
551
+ get transformMatrix() {
552
+ const m = this.#transformMatrix;
553
+ return { a: m.a, b: m.b, c: m.c, d: m.d, e: m.e, f: m.f };
554
+ }
555
+ }
556
+ __decorate$b([
557
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
558
+ ], UiElement.prototype, "rotate", void 0);
559
+ __decorate$b([
560
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
561
+ ], UiElement.prototype, "scaleX", void 0);
562
+ __decorate$b([
563
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
564
+ ], UiElement.prototype, "scaleY", void 0);
565
+ __decorate$b([
566
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
567
+ ], UiElement.prototype, "translateX", void 0);
568
+ __decorate$b([
569
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
570
+ ], UiElement.prototype, "translateY", void 0);
571
+ __decorate$b([
572
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
573
+ ], UiElement.prototype, "opacity", void 0);
574
+ class PresentationElement extends UiElement {
575
+ propertyChangedCallback(name, old, val, first) {
576
+ super.propertyChangedCallback(name, old, val, first);
577
+ if (!first) {
578
+ switch (name) {
579
+ case 'stroke':
580
+ case 'lineWidth':
581
+ case 'lineJoin':
582
+ case 'lineCap':
583
+ case 'dashArray':
584
+ case 'fill':
585
+ if (!pacemCore.Utils.isNull(this.stage)) {
586
+ this.stage.draw(this);
587
+ }
588
+ break;
589
+ }
590
+ }
591
+ }
592
+ }
593
+ __decorate$b([
594
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
595
+ ], PresentationElement.prototype, "stroke", void 0);
596
+ __decorate$b([
597
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
598
+ ], PresentationElement.prototype, "fill", void 0);
599
+ __decorate$b([
600
+ pacemCore.Watch({
601
+ emit: false, converter: {
602
+ convert: (attr) => attr?.split(',').map(i => parseInt(i)).filter(i => !Number.isNaN(i)),
603
+ convertBack: (prop) => prop?.join(',')
604
+ }
605
+ })
606
+ ], PresentationElement.prototype, "dashArray", void 0);
607
+ __decorate$b([
608
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
609
+ ], PresentationElement.prototype, "lineWidth", void 0);
610
+ __decorate$b([
611
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
612
+ ], PresentationElement.prototype, "lineJoin", void 0);
613
+ __decorate$b([
614
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
615
+ ], PresentationElement.prototype, "lineCap", void 0);
616
+ class ShapeElement extends PresentationElement {
617
+ propertyChangedCallback(name, old, val, first) {
618
+ super.propertyChangedCallback(name, old, val, first);
619
+ if (!first) {
620
+ switch (name) {
621
+ case 'data':
622
+ this.stage?.draw(this);
623
+ break;
624
+ }
625
+ }
626
+ }
627
+ viewActivatedCallback() {
628
+ super.viewActivatedCallback();
629
+ this.recomputeShape();
630
+ }
631
+ recomputeShape() {
632
+ const { pathData, vertices, boundingRect } = this.getShapeGeometry();
633
+ this.#vertices = vertices;
634
+ this.#boundingRect = boundingRect;
635
+ this.data = pathData;
636
+ }
637
+ get pathData() {
638
+ return this.data;
639
+ }
640
+ #boundingRect;
641
+ get boundingRect() {
642
+ return this.#boundingRect;
643
+ }
644
+ #vertices;
645
+ get vertices() {
646
+ return this.#vertices;
647
+ }
648
+ }
649
+ __decorate$b([
650
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
651
+ ], ShapeElement.prototype, "data", void 0);
652
+
653
+ var __decorate$a = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
654
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
655
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
656
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
657
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
658
+ };
659
+ //namespace Pacem.Components.Drawing {
660
+ let PacemGroupElement = class PacemGroupElement extends PresentationElement {
661
+ validate(item) {
662
+ return item instanceof DrawableElement && item.parent === this;
663
+ }
664
+ #children = [];
665
+ get childDrawables() {
666
+ return this.#children;
667
+ }
668
+ propertyChangedCallback(name, old, val, first) {
669
+ super.propertyChangedCallback(name, old, val, first);
670
+ switch (name) {
671
+ case 'items':
672
+ case 'datasource':
673
+ this.#children = (val || []);
674
+ const scene = this.stage;
675
+ if (!pacemCore.Utils.isNull(scene)) {
676
+ scene.draw(this, true);
677
+ }
678
+ break;
679
+ }
680
+ }
681
+ };
682
+ __decorate$a([
683
+ pacemCore.Watch({ emit: false })
684
+ ], PacemGroupElement.prototype, "datasource", void 0);
685
+ PacemGroupElement = __decorate$a([
686
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME + '-group' })
687
+ ], PacemGroupElement);
688
+
689
+ var __decorate$9 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
690
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
691
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
692
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
693
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
694
+ };
695
+ var PacemEllipseElement_1, PacemCircleElement_1;
696
+ //namespace Pacem.Components.Drawing {
697
+ function full(c, rx, ry) {
698
+ const d = 2 * rx, cx = c.x, cy = c.y;
699
+ return {
700
+ pathData: `M ${cx} ${cy} m ${-rx},0 a ${rx},${ry} 0 1,1 ${d},0 a ${rx},${ry} 0 1,1 ${-d},0`,
701
+ vertices: [],
702
+ boundingRect: { x: cx - rx, y: cy - ry, width: 2 * rx, height: 2 * ry }
703
+ };
704
+ }
705
+ function sect(c, rx, ry, start, end) {
706
+ const degToRad = Math.PI / 180;
707
+ const s = degToRad * start, e = degToRad * end;
708
+ //
709
+ const polar = (theta) => rx * ry / Math.sqrt(Math.pow(Math.cos(theta) * ry, 2) + Math.pow(Math.sin(theta) * rx, 2));
710
+ const rhoStart = polar(s), rhoEnd = polar(e);
711
+ const cartesian = (rho, theta) => {
712
+ return { x: rho * Math.cos(theta), y: rho * Math.sin(theta) };
713
+ };
714
+ const cartStart = cartesian(rhoStart, s), cartEnd = cartesian(rhoEnd, e);
715
+ const p0 = { x: c.x + cartStart.x, y: c.y + cartStart.y }, p1 = { x: c.x + cartEnd.x, y: c.y + cartEnd.y };
716
+ let boundingRect = pacemFoundation.Rect.expand(c, p0, p1);
717
+ if (end < start)
718
+ end += 360;
719
+ if (start <= 0 && end > 0 || end >= 360) {
720
+ boundingRect = pacemFoundation.Rect.expand(boundingRect, { x: c.x + rx, y: c.y });
721
+ }
722
+ if (start <= 90 && end > 90 || end >= 450) {
723
+ boundingRect = pacemFoundation.Rect.expand(boundingRect, { x: c.x, y: c.y + ry });
724
+ }
725
+ if (start <= 180 && end > 180 || end >= 540) {
726
+ boundingRect = pacemFoundation.Rect.expand(boundingRect, { x: c.x - rx, y: c.y });
727
+ }
728
+ if (start <= 270 && end > 270 || end >= 630) {
729
+ boundingRect = pacemFoundation.Rect.expand(boundingRect, { x: c.x, y: c.y - ry });
730
+ }
731
+ const flag = e - s > Math.PI ? '1' : '0';
732
+ return {
733
+ pathData: `M ${p0.x} ${p0.y} A ${rx},${ry} 0 ${flag},1 ${p1.x},${p1.y} L ${c.x},${c.y} Z`, vertices: [p0, p1], boundingRect
734
+ };
735
+ }
736
+ function getShapeGeometry(c, rx, ry, start, end) {
737
+ start ??= 0, end ??= 0;
738
+ start %= 360;
739
+ end %= 360;
740
+ while (start < 0)
741
+ start += 360;
742
+ while (end < start)
743
+ end += 360;
744
+ const threesixty = (start - end).isCloseTo(0);
745
+ return threesixty ? full(c, rx, ry) : sect(c, rx, ry, start, end);
746
+ }
747
+ let PacemEllipseElement = PacemEllipseElement_1 = class PacemEllipseElement extends ShapeElement {
748
+ propertyChangedCallback(name, old, val, first) {
749
+ super.propertyChangedCallback(name, old, val, first);
750
+ if (!first) {
751
+ switch (name) {
752
+ case 'center':
753
+ case 'rx':
754
+ case 'ry':
755
+ case 'start':
756
+ case 'end':
757
+ this.recomputeShape();
758
+ break;
759
+ }
760
+ }
761
+ }
762
+ getPathData() {
763
+ const a = this.rx, b = this.ry, c = this.center, s = this.start ?? 0, e = this.end ?? 0;
764
+ if (!pacemCore.Utils.isNull(c) && !pacemCore.Utils.isNull(a) && !pacemCore.Utils.isNull(b)) {
765
+ return PacemEllipseElement_1.getPathData(c, a, b, s, e);
766
+ }
767
+ return null;
768
+ }
769
+ getShapeGeometry() {
770
+ const center = this.center ?? { x: 0, y: 0 };
771
+ const a = this.rx ?? 0, b = this.ry ?? 0;
772
+ return getShapeGeometry(center, a, b, this.start, this.end);
773
+ }
774
+ static getPathData(c = { x: NaN, y: NaN }, rx = NaN, ry = NaN, start, end) {
775
+ const { pathData } = getShapeGeometry(c, rx, ry, start, end);
776
+ return pathData;
777
+ }
778
+ };
779
+ __decorate$9([
780
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Point })
781
+ ], PacemEllipseElement.prototype, "center", void 0);
782
+ __decorate$9([
783
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
784
+ ], PacemEllipseElement.prototype, "rx", void 0);
785
+ __decorate$9([
786
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
787
+ ], PacemEllipseElement.prototype, "ry", void 0);
788
+ __decorate$9([
789
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
790
+ ], PacemEllipseElement.prototype, "start", void 0);
791
+ __decorate$9([
792
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
793
+ ], PacemEllipseElement.prototype, "end", void 0);
794
+ PacemEllipseElement = PacemEllipseElement_1 = __decorate$9([
795
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME + '-ellipse' })
796
+ ], PacemEllipseElement);
797
+ let PacemCircleElement = PacemCircleElement_1 = class PacemCircleElement extends ShapeElement {
798
+ propertyChangedCallback(name, old, val, first) {
799
+ super.propertyChangedCallback(name, old, val, first);
800
+ if (!first) {
801
+ switch (name) {
802
+ case 'center':
803
+ case 'radius':
804
+ case 'start':
805
+ case 'end':
806
+ this.recomputeShape();
807
+ break;
808
+ }
809
+ }
810
+ }
811
+ getPathData() {
812
+ const r = this.radius, c = this.center;
813
+ if (!pacemCore.Utils.isNull(c) && !pacemCore.Utils.isNull(r)) {
814
+ return PacemCircleElement_1.getPathData(c, r, this.start, this.end);
815
+ }
816
+ return null;
817
+ }
818
+ getShapeGeometry() {
819
+ const center = this.center ?? { x: 0, y: 0 };
820
+ const r = this.radius ?? 0;
821
+ return getShapeGeometry(center, r, r, this.start, this.end);
822
+ }
823
+ static getPathData(c = { x: NaN, y: NaN }, r = NaN, start, end) {
824
+ return PacemEllipseElement.getPathData(c, r, r, start, end);
825
+ }
826
+ };
827
+ __decorate$9([
828
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Point })
829
+ ], PacemCircleElement.prototype, "center", void 0);
830
+ __decorate$9([
831
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
832
+ ], PacemCircleElement.prototype, "radius", void 0);
833
+ __decorate$9([
834
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
835
+ ], PacemCircleElement.prototype, "start", void 0);
836
+ __decorate$9([
837
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
838
+ ], PacemCircleElement.prototype, "end", void 0);
839
+ PacemCircleElement = PacemCircleElement_1 = __decorate$9([
840
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME + '-circle' })
841
+ ], PacemCircleElement);
842
+
843
+ var __decorate$8 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
844
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
845
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
846
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
847
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
848
+ };
849
+ var PacemRectElement_1;
850
+ //namespace Pacem.Components.Drawing {
851
+ /*
852
+ r="4" // every corner has a rx equalt o ry equal to 8 units
853
+ r="4,8 cut" // every corner has a rx equal to 4px and a ry equal to 8px (cut corners)
854
+ r="4,8 cut 5,6 3,20% round 50%,4" // top-left corner has a rx equal to 4px and a ry equal to 8px (cut corner), top-right corner has a rx equal to 5px and a ry equal to 6px,
855
+ // bottom-right corner has a rx equal to 3px and a ry equal to 20% the height,
856
+ // bottom-left corner has a rx equal to 50% the width and a ry equal to 4px.
857
+
858
+ */
859
+ function parseCornerRadius(radius) {
860
+ const rx = radius[2], ry = radius[4] ?? rx, type = radius[6] === 'cut' ? CornerType.Cut : CornerType.Rounded;
861
+ return { rx: parseCornerRadiusComponent(rx), ry: parseCornerRadiusComponent(ry), type };
862
+ }
863
+ function parseCornerRadiusComponent(radius) {
864
+ const val = parseFloat(radius);
865
+ return { value: val, unit: radius.endsWith('%') ? 'pct' : 'u' };
866
+ }
867
+ function stringifyCornerRadiusComponent(radius) {
868
+ return `${radius.value}${radius.unit === 'pct' ? '%' : ''}`;
869
+ }
870
+ const CORNERS_PATTERN = /(([\d\.]+%?)(\s*,?\s*([\d\.]+%?))?(\s+(cut|round))?)/g;
871
+ function parseCornerRadii(radii) {
872
+ let numbers;
873
+ const acc = [];
874
+ while (numbers = CORNERS_PATTERN.exec(radii)) {
875
+ acc.push(numbers);
876
+ }
877
+ switch (acc.length) {
878
+ case 1:
879
+ const single = parseCornerRadius(acc[0]);
880
+ return [single, single, single, single];
881
+ case 4:
882
+ const topLeft = parseCornerRadius(acc[0]);
883
+ const topRight = parseCornerRadius(acc[1]);
884
+ const bottomRight = parseCornerRadius(acc[2]);
885
+ const bottomLeft = parseCornerRadius(acc[3]);
886
+ return [topLeft, topRight, bottomRight, bottomLeft];
887
+ default:
888
+ return null;
889
+ }
890
+ }
891
+ function stringifyCornerRadii(radii) {
892
+ const topLeft = radii[0], topRight = radii[1], bottomRight = radii[2], bottomLeft = radii[3];
893
+ const tlX = stringifyCornerRadiusComponent(topLeft.rx), tlY = stringifyCornerRadiusComponent(topLeft.ry);
894
+ const trX = stringifyCornerRadiusComponent(topRight.rx), trY = stringifyCornerRadiusComponent(topRight.ry);
895
+ const brX = stringifyCornerRadiusComponent(bottomRight.rx), brY = stringifyCornerRadiusComponent(bottomRight.ry);
896
+ const blX = stringifyCornerRadiusComponent(bottomLeft.rx), blY = stringifyCornerRadiusComponent(bottomLeft.ry);
897
+ return `${tlX},${tlY} ${trX},${trY} ${brX},${brY} ${blX},${blY}`;
898
+ }
899
+ var CornerType;
900
+ (function (CornerType) {
901
+ CornerType["Rounded"] = "rounded";
902
+ CornerType["Cut"] = "cut";
903
+ })(CornerType || (CornerType = {}));
904
+ let PacemRectElement = PacemRectElement_1 = class PacemRectElement extends ShapeElement {
905
+ propertyChangedCallback(name, old, val, first) {
906
+ super.propertyChangedCallback(name, old, val, first);
907
+ if (!first && (name === 'x' || name === 'y' || name === 'w' || name === 'h' || name === 'r' || name === 'cornerType')) {
908
+ this.recomputeShape();
909
+ }
910
+ }
911
+ getPathData() {
912
+ const x = this.x, y = this.y, w = this.w, h = this.h;
913
+ let r = this.r ?? { rx: { value: 0 }, ry: { value: 0 }, type: CornerType.Rounded };
914
+ if (!pacemCore.Utils.isArray(r)) {
915
+ r = [r, r, r, r];
916
+ }
917
+ // forgiving behavior
918
+ r = r.map(i => { return typeof i === 'number' ? { rx: { value: i }, ry: { value: i }, type: this.cornerType } : i; });
919
+ if (!pacemCore.Utils.isNull(x) && !pacemCore.Utils.isNull(y) && !pacemCore.Utils.isNull(w) && !pacemCore.Utils.isNull(h)) {
920
+ return PacemRectElement_1.getPathData(x, y, w, h, r);
921
+ }
922
+ return null;
923
+ }
924
+ getShapeGeometry() {
925
+ const x = this.x, y = this.y, x1 = x + this.w, y1 = y + this.h;
926
+ return {
927
+ pathData: this.getPathData(), vertices: [{ x, y }, { x: x1, y }, { x: x1, y: y1 }, { x, y: y1 }], boundingRect: { x, y, width: this.w, height: this.h }
928
+ };
929
+ }
930
+ static getPathData(x = NaN, y = NaN, w = NaN, h = NaN, r = null) {
931
+ if (!r) {
932
+ return `M ${x} ${y} h ${w} v ${h} h ${-w} z`;
933
+ }
934
+ if (!pacemCore.Utils.isArray(r)) {
935
+ r = [r, r, r, r];
936
+ }
937
+ const tl = r[0], tr = r[1], br = r[2], bl = r[3];
938
+ const vx = (rx) => rx.unit === 'pct' ? rx.value * .01 * w : rx.value;
939
+ const vy = (ry) => ry.unit === 'pct' ? ry.value * .01 * h : ry.value;
940
+ const tlX = vx(tl.rx), tlY = vy(tl.ry);
941
+ const trX = vx(tr.rx), trY = vy(tr.ry);
942
+ const brX = vx(br.rx), brY = vy(br.ry);
943
+ const blX = vx(bl.rx), blY = vy(bl.ry);
944
+ let retval = `M ${x},${y + tlY}`;
945
+ // top-left
946
+ switch (tl.type) {
947
+ case 'cut':
948
+ retval += ` l ${tlX},${-tlY}`;
949
+ break;
950
+ default:
951
+ retval += ` a ${tlX} ${tlY} 0 0 1 ${tlX} ${-tlY}`;
952
+ break;
953
+ }
954
+ retval += ` h ${w - tlX - trX}`;
955
+ // top-right
956
+ switch (tr.type) {
957
+ case 'cut':
958
+ retval += ` l ${trX},${trY}`;
959
+ break;
960
+ default:
961
+ retval += ` a ${trX} ${trY} 0 0 1 ${trX} ${trY}`;
962
+ break;
963
+ }
964
+ retval += ` v ${h - trY - brY}`;
965
+ // bottom-right
966
+ switch (br.type) {
967
+ case 'cut':
968
+ retval += ` l ${-brX},${brY}`;
969
+ break;
970
+ default:
971
+ retval += ` a ${brX} ${brY} 0 0 1 ${-brX} ${brY}`;
972
+ break;
973
+ }
974
+ retval += ` h ${-(w - brX - blX)}`;
975
+ // bottom-left
976
+ switch (bl.type) {
977
+ case 'cut':
978
+ retval += ` l ${-blX},${-blY}`;
979
+ break;
980
+ default:
981
+ retval += ` a ${blX} ${blY} 0 0 1 ${-blX} ${-blY}`;
982
+ break;
983
+ }
984
+ return retval + ' z';
985
+ }
986
+ };
987
+ __decorate$8([
988
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
989
+ ], PacemRectElement.prototype, "x", void 0);
990
+ __decorate$8([
991
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
992
+ ], PacemRectElement.prototype, "y", void 0);
993
+ __decorate$8([
994
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
995
+ ], PacemRectElement.prototype, "w", void 0);
996
+ __decorate$8([
997
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
998
+ ], PacemRectElement.prototype, "h", void 0);
999
+ __decorate$8([
1000
+ pacemCore.Watch({
1001
+ emit: false, converter: {
1002
+ convert: attr => parseCornerRadii(attr),
1003
+ convertBack: (radii) => stringifyCornerRadii(radii)
1004
+ }
1005
+ })
1006
+ ], PacemRectElement.prototype, "r", void 0);
1007
+ __decorate$8([
1008
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
1009
+ ], PacemRectElement.prototype, "cornerType", void 0);
1010
+ PacemRectElement = PacemRectElement_1 = __decorate$8([
1011
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME + '-rect' })
1012
+ ], PacemRectElement);
1013
+
1014
+ var __decorate$7 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
1015
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1016
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1017
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1018
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1019
+ };
1020
+ var PacemLineElement_1;
1021
+ //namespace Pacem.Components.Drawing {
1022
+ let PacemLineElement = PacemLineElement_1 = class PacemLineElement extends ShapeElement {
1023
+ propertyChangedCallback(name, old, val, first) {
1024
+ super.propertyChangedCallback(name, old, val, first);
1025
+ if (!first) {
1026
+ switch (name) {
1027
+ case 'from':
1028
+ case 'to':
1029
+ this.recomputeShape();
1030
+ break;
1031
+ }
1032
+ }
1033
+ }
1034
+ getShapeGeometry() {
1035
+ const from = this.from, to = this.to;
1036
+ if (pacemCore.Utils.isNull(from) || pacemCore.Utils.isNull(to)) {
1037
+ return Shape.empty();
1038
+ }
1039
+ const x0 = from.x, y0 = from.y, x1 = to.x, y1 = to.y;
1040
+ const boundingRect = { x: Math.min(x0, x1), y: Math.min(y0, y1), width: Math.abs(x0 - x1), height: Math.abs(y0 - y1) };
1041
+ return { pathData: this.getPathData(), vertices: [from, to], boundingRect };
1042
+ }
1043
+ getPathData() {
1044
+ const from = this.from, to = this.to;
1045
+ if (!pacemCore.Utils.isNull(from) && !pacemCore.Utils.isNull(to)) {
1046
+ return PacemLineElement_1.getPathData(from, to);
1047
+ }
1048
+ return null;
1049
+ }
1050
+ static getPathData(from = { x: NaN, y: NaN }, to = { x: NaN, y: NaN }) {
1051
+ const x0 = from.x, y0 = from.y, x1 = to.x, y1 = to.y;
1052
+ return `M ${x0} ${y0} L ${x1} ${y1}`;
1053
+ }
1054
+ };
1055
+ __decorate$7([
1056
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Point })
1057
+ ], PacemLineElement.prototype, "from", void 0);
1058
+ __decorate$7([
1059
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Point })
1060
+ ], PacemLineElement.prototype, "to", void 0);
1061
+ PacemLineElement = PacemLineElement_1 = __decorate$7([
1062
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME + '-line' })
1063
+ ], PacemLineElement);
1064
+
1065
+ var __decorate$6 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
1066
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1067
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1068
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1069
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1070
+ };
1071
+ //namespace Pacem.Components.Drawing {
1072
+ let PacemPathElement = class PacemPathElement extends ShapeElement {
1073
+ constructor() {
1074
+ super(...arguments);
1075
+ this.getPathData = () => this.d;
1076
+ }
1077
+ propertyChangedCallback(name, old, val, first) {
1078
+ super.propertyChangedCallback(name, old, val, first);
1079
+ if (name === 'd' && !first) {
1080
+ this.recomputeShape();
1081
+ }
1082
+ }
1083
+ getShapeGeometry() {
1084
+ return { pathData: this.getPathData(), /* TODO: parse d */ boundingRect: null, vertices: [] };
1085
+ }
1086
+ };
1087
+ __decorate$6([
1088
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
1089
+ ], PacemPathElement.prototype, "d", void 0);
1090
+ PacemPathElement = __decorate$6([
1091
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME + '-path' })
1092
+ ], PacemPathElement);
1093
+
1094
+ var __decorate$5 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
1095
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1096
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1097
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1098
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1099
+ };
1100
+ var PacemPolygonElement_1;
1101
+ //namespace Pacem.Components.Drawing {
1102
+ let PacemPolygonElement = PacemPolygonElement_1 = class PacemPolygonElement extends ShapeElement {
1103
+ propertyChangedCallback(name, old, val, first) {
1104
+ super.propertyChangedCallback(name, old, val, first);
1105
+ if (!first) {
1106
+ switch (name) {
1107
+ case 'radius':
1108
+ case 'starIndent':
1109
+ case 'sides':
1110
+ this.recomputeShape();
1111
+ break;
1112
+ }
1113
+ }
1114
+ }
1115
+ getPathData() {
1116
+ const sides = this.sides, radius = this.radius, center = this.center;
1117
+ if (!pacemCore.Utils.isNull(sides) && !pacemCore.Utils.isNull(radius)) {
1118
+ return PacemPolygonElement_1.getPathData(center, radius, sides, this.starIndent);
1119
+ }
1120
+ return null;
1121
+ }
1122
+ getShapeGeometry() {
1123
+ const c = this.center ?? { x: 0, y: 0 }, r = this.radius ?? 0, sides = this.sides ?? 3, si = this.starIndent;
1124
+ if (sides < 3) {
1125
+ return Shape.empty();
1126
+ }
1127
+ return PacemPolygonElement_1.getShapeGeometry(c, r, sides, si);
1128
+ }
1129
+ static getShapeGeometry(center, radius, sides, starIndent = .0) {
1130
+ const p0 = { x: center.x, y: center.y - radius };
1131
+ let retval = `M ${p0.x} ${(p0.y)}`;
1132
+ const vertices = [p0];
1133
+ const theta = 2 * Math.PI / sides, theta2 = .5 * theta, isStar = starIndent > 0, apothem = radius * Math.cos(theta2);
1134
+ for (let j = 1; j < sides; j++) {
1135
+ const angle = j * theta, x = center.x + Math.sin(angle) * radius, y = center.y - Math.cos(angle) * radius;
1136
+ if (isStar) {
1137
+ const innerRadius = apothem * (1.0 - starIndent);
1138
+ const angle2 = angle - theta2, x1 = center.x + Math.sin(angle2) * innerRadius, y1 = center.y - Math.cos(angle2) * innerRadius;
1139
+ retval += ` L ${x1} ${y1} L ${x} ${y}`;
1140
+ vertices.push({ x: x1, y: y1 });
1141
+ }
1142
+ else {
1143
+ retval += ` L ${x} ${y}`;
1144
+ }
1145
+ vertices.push({ x, y });
1146
+ }
1147
+ if (isStar) {
1148
+ const innerRadius = apothem * (1.0 - starIndent);
1149
+ const angle2 = 2 * Math.PI - theta2, x1 = center.x + Math.sin(angle2) * innerRadius, y1 = center.y - Math.cos(angle2) * innerRadius;
1150
+ retval += ` L ${x1} ${y1}`;
1151
+ vertices.push({ x: x1, y: y1 });
1152
+ }
1153
+ vertices.push(p0);
1154
+ const width = radius * 2;
1155
+ return {
1156
+ pathData: retval + ' Z', vertices, boundingRect: { x: p0.x - radius, y: p0.y, width, height: width }
1157
+ };
1158
+ }
1159
+ static getPathData(center, radius, sides, starIndent = .0) {
1160
+ const { pathData } = PacemPolygonElement_1.getShapeGeometry(center, radius, sides, starIndent);
1161
+ return pathData;
1162
+ }
1163
+ };
1164
+ __decorate$5([
1165
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
1166
+ ], PacemPolygonElement.prototype, "sides", void 0);
1167
+ __decorate$5([
1168
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
1169
+ ], PacemPolygonElement.prototype, "radius", void 0);
1170
+ __decorate$5([
1171
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Point })
1172
+ ], PacemPolygonElement.prototype, "center", void 0);
1173
+ __decorate$5([
1174
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
1175
+ ], PacemPolygonElement.prototype, "starIndent", void 0);
1176
+ PacemPolygonElement = PacemPolygonElement_1 = __decorate$5([
1177
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME + '-polygon' })
1178
+ ], PacemPolygonElement);
1179
+
1180
+ var __decorate$4 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
1181
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1182
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1183
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1184
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1185
+ };
1186
+ var PacemPolylineElement_1;
1187
+ //namespace Pacem.Components.Drawing {
1188
+ const PointArrayOrJsonConverter = {
1189
+ convert: (attr) => {
1190
+ const arr = pacemFoundation.parseAsNumericalArray(attr);
1191
+ if (arr.length % 2 === 0) {
1192
+ const retval = [];
1193
+ for (let j = 0; j < arr.length; j += 2) {
1194
+ retval.push({ x: arr[j], y: arr[j + 1] });
1195
+ }
1196
+ return retval;
1197
+ }
1198
+ return JSON.parse(attr);
1199
+ },
1200
+ convertBack: (prop) => JSON.stringify(prop)
1201
+ };
1202
+ let PacemPolylineElement = PacemPolylineElement_1 = class PacemPolylineElement extends ShapeElement {
1203
+ propertyChangedCallback(name, old, val, first) {
1204
+ super.propertyChangedCallback(name, old, val, first);
1205
+ if (!first) {
1206
+ switch (name) {
1207
+ case 'points':
1208
+ case 'closed':
1209
+ this.recomputeShape();
1210
+ break;
1211
+ }
1212
+ }
1213
+ }
1214
+ static getShapeGeometry(points, closed) {
1215
+ if (pacemCore.Utils.isNullOrEmpty(points)) {
1216
+ return Shape.empty();
1217
+ }
1218
+ let d = '';
1219
+ let xmin = Number.MAX_VALUE, ymin = Number.MAX_VALUE, xmax = Number.MIN_VALUE, ymax = Number.MIN_VALUE;
1220
+ for (let j = 0; j < points.length; j++) {
1221
+ const { x, y } = points[j];
1222
+ d += `${(j === 0 ? 'M' : 'L')} ${x} ${y} `;
1223
+ xmin = Math.min(xmin, x);
1224
+ xmax = Math.max(xmax, x);
1225
+ ymin = Math.min(ymin, y);
1226
+ ymax = Math.max(ymax, y);
1227
+ }
1228
+ const boundingRect = { x: xmin, y: ymin, width: xmax - xmin, height: ymax - ymin };
1229
+ if (closed) {
1230
+ d += 'Z';
1231
+ }
1232
+ return { pathData: d, vertices: points, boundingRect };
1233
+ }
1234
+ getShapeGeometry() {
1235
+ return PacemPolylineElement_1.getShapeGeometry(this.points, this.closed);
1236
+ }
1237
+ getPathData() {
1238
+ const { pathData } = this.getShapeGeometry();
1239
+ return pathData;
1240
+ }
1241
+ static getPathData(points, closed) {
1242
+ const { pathData } = PacemPolylineElement_1.getShapeGeometry(points, closed);
1243
+ return pathData;
1244
+ }
1245
+ };
1246
+ __decorate$4([
1247
+ pacemCore.Watch({ emit: false, converter: PointArrayOrJsonConverter })
1248
+ ], PacemPolylineElement.prototype, "points", void 0);
1249
+ __decorate$4([
1250
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Boolean })
1251
+ ], PacemPolylineElement.prototype, "closed", void 0);
1252
+ PacemPolylineElement = PacemPolylineElement_1 = __decorate$4([
1253
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME + '-polyline' })
1254
+ ], PacemPolylineElement);
1255
+
1256
+ var __decorate$3 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
1257
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1258
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1259
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1260
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1261
+ };
1262
+ //namespace Pacem.Components.Drawing {
1263
+ let PacemImageElement = class PacemImageElement extends UiElement {
1264
+ propertyChangedCallback(name, old, val, first) {
1265
+ super.propertyChangedCallback(name, old, val, first);
1266
+ if (!first) {
1267
+ switch (name) {
1268
+ case 'src':
1269
+ case 'x':
1270
+ case 'y':
1271
+ case 'width':
1272
+ case 'height':
1273
+ this.stage?.draw(this);
1274
+ break;
1275
+ }
1276
+ }
1277
+ }
1278
+ };
1279
+ __decorate$3([
1280
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
1281
+ ], PacemImageElement.prototype, "src", void 0);
1282
+ __decorate$3([
1283
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
1284
+ ], PacemImageElement.prototype, "x", void 0);
1285
+ __decorate$3([
1286
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
1287
+ ], PacemImageElement.prototype, "y", void 0);
1288
+ __decorate$3([
1289
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
1290
+ ], PacemImageElement.prototype, "width", void 0);
1291
+ __decorate$3([
1292
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
1293
+ ], PacemImageElement.prototype, "height", void 0);
1294
+ PacemImageElement = __decorate$3([
1295
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME + '-image' })
1296
+ ], PacemImageElement);
1297
+
1298
+ var __decorate$2 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
1299
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1300
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1301
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1302
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1303
+ };
1304
+ //namespace Pacem.Components.Drawing {
1305
+ let PacemTextElement = class PacemTextElement extends UiElement {
1306
+ propertyChangedCallback(name, old, val, first) {
1307
+ if (!first) {
1308
+ switch (name) {
1309
+ case 'text':
1310
+ case 'color':
1311
+ case 'fontFamily':
1312
+ case 'fontSize':
1313
+ case 'fontWeight':
1314
+ case 'fontStyle':
1315
+ case 'anchor':
1316
+ if (!pacemCore.Utils.isNull(this.stage)) {
1317
+ this.stage.draw(this);
1318
+ }
1319
+ break;
1320
+ }
1321
+ }
1322
+ }
1323
+ };
1324
+ __decorate$2([
1325
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
1326
+ ], PacemTextElement.prototype, "text", void 0);
1327
+ __decorate$2([
1328
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
1329
+ ], PacemTextElement.prototype, "color", void 0);
1330
+ __decorate$2([
1331
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
1332
+ ], PacemTextElement.prototype, "fontFamily", void 0);
1333
+ __decorate$2([
1334
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Number })
1335
+ ], PacemTextElement.prototype, "fontSize", void 0);
1336
+ __decorate$2([
1337
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
1338
+ ], PacemTextElement.prototype, "fontWeight", void 0);
1339
+ __decorate$2([
1340
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
1341
+ ], PacemTextElement.prototype, "fontStyle", void 0);
1342
+ __decorate$2([
1343
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.Point })
1344
+ ], PacemTextElement.prototype, "anchor", void 0);
1345
+ __decorate$2([
1346
+ pacemCore.Watch({ emit: false, converter: pacemCore.PropertyConverters.String })
1347
+ ], PacemTextElement.prototype, "textAnchor", void 0);
1348
+ PacemTextElement = __decorate$2([
1349
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME + '-text' })
1350
+ ], PacemTextElement);
1351
+
1352
+ //namespace Pacem.Components.Drawing {
1353
+ class AdapterUtils {
1354
+ static stageDispatch(stage, type, evt) {
1355
+ if (stage instanceof EventTarget) {
1356
+ stage.dispatchEvent(new StageEvent('stage' + type, stage, evt, stage.transformMatrix));
1357
+ }
1358
+ }
1359
+ static isValidViewbox(viewbox) {
1360
+ return !pacemCore.Utils.isNullOrEmpty(viewbox) && pacemFoundation.Rect.isRect(viewbox) && Number.isFinite(viewbox.x) // isFinite includes NaN check
1361
+ && Number.isFinite(viewbox.y) && Number.isFinite(viewbox.width) && Number.isFinite(viewbox.height);
1362
+ }
1363
+ static itemDispatch(target, type, offset) {
1364
+ if (pacemCore.Utils.isNull(target?.stage)) {
1365
+ return false;
1366
+ }
1367
+ var dragArgs, originalEvent, evtType;
1368
+ if (offset instanceof Event) {
1369
+ originalEvent = offset;
1370
+ }
1371
+ else {
1372
+ dragArgs = { item: target, offset: offset };
1373
+ }
1374
+ if (typeof type === 'string') {
1375
+ evtType = type;
1376
+ }
1377
+ else {
1378
+ evtType = type.type;
1379
+ originalEvent = type.originalEvent;
1380
+ }
1381
+ const m = target.stage.transformMatrix;
1382
+ const evt = () => offset instanceof Event
1383
+ ? new DrawableEvent(evtType, target, originalEvent, m)
1384
+ : new DragEvent(evtType, { detail: dragArgs, cancelable: evtType === pacemCore.UI.DragDropEventType.Init || evtType === pacemCore.UI.DragDropEventType.Drag }, originalEvent, m);
1385
+ const itemevt = offset instanceof Event
1386
+ ? new DrawableEvent('item' + evtType, target, originalEvent, m)
1387
+ : new DragEvent('item' + evtType, { detail: dragArgs, cancelable: evtType === pacemCore.UI.DragDropEventType.Init || evtType === pacemCore.UI.DragDropEventType.Drag }, originalEvent, m);
1388
+ var prevent = false;
1389
+ if (target instanceof EventTarget) {
1390
+ const evnt = evt();
1391
+ target.dispatchEvent(evnt);
1392
+ prevent = evnt.defaultPrevented;
1393
+ }
1394
+ target.stage.dispatchEvent(itemevt);
1395
+ // was the event (in one of its forms) rejected?
1396
+ return prevent || itemevt.defaultPrevented;
1397
+ }
1398
+ }
1399
+
1400
+ const JPEG_QUALITY = .9;
1401
+ class Pacem2DAdapterElement extends pacemCore.PacemEventTarget {
1402
+ constructor() {
1403
+ super(...arguments);
1404
+ this.DefaultShapeValues = {
1405
+ stroke: "#000",
1406
+ lineWidth: 1,
1407
+ fill: "#fff"
1408
+ };
1409
+ }
1410
+ snapshotElement(element, bgColor, type, quality) {
1411
+ const jpeg = !pacemCore.Utils.isNullOrEmpty(bgColor), mime = type ?? (jpeg ? 'image/jpeg' : null), compression = quality ?? (jpeg ? JPEG_QUALITY : null);
1412
+ return pacemCore.Utils.snapshotElement(element, bgColor, mime, compression);
1413
+ }
1414
+ }
1415
+
1416
+ var __decorate$1 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
1417
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1418
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1419
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1420
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1421
+ };
1422
+ //namespace Pacem.Components.Drawing {
1423
+ const CANVAS_SCENE_VAR = 'pacem:2d-canvas-scene';
1424
+ const PARENT_MATRIX_VAR = 'pacem:2d-parent-matrix';
1425
+ const WORLD_MATRIX_VAR = 'pacem:2d-world-matrix';
1426
+ const SETVAR$1 = pacemCore.CustomElementUtils.setAttachedPropertyValue, GETVAR$1 = pacemCore.CustomElementUtils.getAttachedPropertyValue;
1427
+ function isNone(fillOrStroke) {
1428
+ return fillOrStroke === 'none' || pacemCore.Utils.isNullOrEmpty(fillOrStroke);
1429
+ }
1430
+ function fallback$1(v, f) {
1431
+ return pacemCore.Utils.isNull(v) ? f : v;
1432
+ }
1433
+ /** Implementation postponed. Focus on SVG adapter. */
1434
+ let PacemCanvasAdapterElement = class PacemCanvasAdapterElement extends Pacem2DAdapterElement {
1435
+ constructor() {
1436
+ super(...arguments);
1437
+ this._pointer = {
1438
+ page: { x: Number.NaN, y: Number.NaN }, screen: { x: Number.NaN, y: Number.NaN }, client: { x: Number.NaN, y: Number.NaN }
1439
+ };
1440
+ this._dragInitHandler = (evt) => {
1441
+ const hitTarget = this._hitTarget;
1442
+ if (pacemCore.Utils.isNull(hitTarget) || !isUiObject(hitTarget) || !hitTarget.draggable) {
1443
+ evt.preventDefault();
1444
+ return;
1445
+ }
1446
+ const args = evt.detail, drawable = hitTarget, initialMatrix = hitTarget.transformMatrix ?? pacemFoundation.Matrix2D.identity, parentMatrix = GETVAR$1(hitTarget, PARENT_MATRIX_VAR, pacemFoundation.Matrix2D.identity);
1447
+ args.data = {
1448
+ item: drawable,
1449
+ initialTransformMatrix: initialMatrix,
1450
+ parentMatrix
1451
+ };
1452
+ const reject = AdapterUtils.itemDispatch(drawable, evt, { x: 0, y: 0 });
1453
+ if (reject) {
1454
+ // reject dragging
1455
+ evt.preventDefault();
1456
+ }
1457
+ };
1458
+ this._draggingHandler = (evt) => {
1459
+ pacemCore.avoidHandler(evt);
1460
+ this._dragging = true;
1461
+ const args = evt.detail;
1462
+ const data = args.data;
1463
+ const screenOffset = { x: args.currentPosition.x - args.origin.x, y: args.currentPosition.y - args.origin.y };
1464
+ const offset = {
1465
+ x: screenOffset.x * data.parentMatrix.a + data.initialTransformMatrix.e,
1466
+ y: screenOffset.y * data.parentMatrix.d + data.initialTransformMatrix.f
1467
+ };
1468
+ //console.log(`current pos: ${args.currentPosition.x},${args.currentPosition.y}`);
1469
+ //console.log(`origin pos: ${args.origin.x},${args.origin.y}`);
1470
+ //console.log(`screen offset: ${screenOffset.x},${screenOffset.y}`);
1471
+ //console.log(`offset: ${offset.x},${offset.y}`);
1472
+ //console.log(data.item.transformMatrix);
1473
+ //console.log(GETVAR(data.item, PARENT_MATRIX_VAR));
1474
+ //console.log(GETVAR(data.item, WORLD_MATRIX_VAR));
1475
+ //console.log(data.initialTransformMatrix);
1476
+ const stageTransformMatrix = data.item.stage.transformMatrix;
1477
+ const rejected = AdapterUtils.itemDispatch(data.item, evt, { x: screenOffset.x * stageTransformMatrix.a + stageTransformMatrix.e, y: screenOffset.y * stageTransformMatrix.d + stageTransformMatrix.f });
1478
+ if (!rejected) {
1479
+ if (data.item instanceof UiElement) {
1480
+ data.item.translateX = offset.x;
1481
+ data.item.translateY = offset.y;
1482
+ }
1483
+ else {
1484
+ const init = data.initialTransformMatrix, actual = { a: init.a, b: init.b, c: init.c, d: init.d, e: offset.x, f: offset.y };
1485
+ pacemCore.Utils.extend(data.item, { transformMatrix: actual });
1486
+ }
1487
+ // console.log(data.item.transformMatrix);
1488
+ }
1489
+ };
1490
+ this._dragEndHandler = (evt) => {
1491
+ this._dragging = false;
1492
+ const args = evt.detail, data = args.data, transform = data.item.transformMatrix;
1493
+ AdapterUtils.itemDispatch(data.item, evt, { x: transform.e, y: transform.f });
1494
+ };
1495
+ // #endregion
1496
+ this._mouseleaveHandler = (evt) => {
1497
+ if (this._dragging) {
1498
+ return;
1499
+ }
1500
+ const hitTarget = this._hitTarget;
1501
+ if (pacemCore.Utils.isNull(hitTarget)) {
1502
+ return;
1503
+ }
1504
+ this._scopeEvent = evt;
1505
+ const nap = { x: Number.NaN, y: Number.NaN };
1506
+ this._pointer = { page: nap, screen: nap, client: nap };
1507
+ const canvas = evt.srcElement;
1508
+ const stage = GETVAR$1(canvas, CANVAS_SCENE_VAR);
1509
+ this._requestDraw(stage);
1510
+ };
1511
+ this._mousemoveHandler = (evt) => {
1512
+ this._scopeEvent = evt;
1513
+ this._pointer = pacemCore.CustomEventUtils.getEventCoordinates(evt);
1514
+ const canvas = evt.srcElement;
1515
+ const stage = GETVAR$1(canvas, CANVAS_SCENE_VAR);
1516
+ this._requestDraw(stage);
1517
+ if (!this._dragging) {
1518
+ if (!pacemCore.Utils.isNull(this._hitTarget)) {
1519
+ AdapterUtils.stageDispatch(stage, 'move', evt);
1520
+ }
1521
+ }
1522
+ };
1523
+ this._mouseDownUpHandler = (evt) => {
1524
+ this._scopeEvent = evt;
1525
+ this._pointer = pacemCore.CustomEventUtils.getEventCoordinates(evt);
1526
+ const canvas = evt.target;
1527
+ if (canvas instanceof HTMLCanvasElement) {
1528
+ const stage = GETVAR$1(canvas, CANVAS_SCENE_VAR), hitTarget = this._hitTarget;
1529
+ const type = evt.type.replace(/^(mouse|touch)/, ''), fineType = type === 'end' ? 'click' : type;
1530
+ const opts = getStageOptions(stage);
1531
+ if (pacemCore.CustomEventUtils.matchModifiers(evt, opts.clickModifiers)) {
1532
+ if (!pacemCore.Utils.isNull(hitTarget) && hitTarget.stage === stage) {
1533
+ AdapterUtils.itemDispatch(hitTarget, fineType, evt);
1534
+ }
1535
+ else {
1536
+ AdapterUtils.stageDispatch(stage, fineType, evt);
1537
+ }
1538
+ }
1539
+ }
1540
+ };
1541
+ this._scenes = new WeakMap();
1542
+ this._handles = new WeakMap();
1543
+ }
1544
+ snapshot(stage, backgroundColor, type, quality) {
1545
+ const scenes = this._scenes;
1546
+ if (scenes.has(stage)) {
1547
+ const ctx2d = scenes.get(stage).context, srcCanvas = ctx2d.canvas;
1548
+ return this.snapshotElement(srcCanvas, backgroundColor, type, quality);
1549
+ }
1550
+ else {
1551
+ return Promise.resolve(null);
1552
+ }
1553
+ }
1554
+ getCanvas(stage) {
1555
+ const scenes = this._scenes;
1556
+ if (scenes.has(stage)) {
1557
+ const ctx2d = scenes.get(stage).context;
1558
+ return ctx2d.canvas;
1559
+ }
1560
+ else {
1561
+ return null;
1562
+ }
1563
+ }
1564
+ _getScreenInverseMatrix(m, offset) {
1565
+ return pacemFoundation.Matrix2D.invert({ a: m.a, b: m.b, c: m.c, d: m.d, e: m.e + offset.x, f: m.f + offset.y });
1566
+ }
1567
+ getTransformMatrix(scene) {
1568
+ const scenes = this._scenes;
1569
+ if (scenes.has(scene)) {
1570
+ return scenes.get(scene).screenInverseMatrix;
1571
+ }
1572
+ return pacemFoundation.Matrix2D.identity;
1573
+ }
1574
+ #dragger;
1575
+ viewActivatedCallback() {
1576
+ super.viewActivatedCallback();
1577
+ const dragDrop = this.#dragger = document.createElement(pacemCore.P + '-drag-drop');
1578
+ dragDrop.mode = pacemCore.UI.DragDataMode.Copy;
1579
+ dragDrop.dropBehavior = pacemCore.UI.DropBehavior.None;
1580
+ dragDrop.spillBehavior = pacemCore.UI.DropTargetMissedBehavior.None;
1581
+ const floater = document.createElement('div');
1582
+ floater.hidden = true;
1583
+ dragDrop.floater = floater;
1584
+ // append
1585
+ const shell = pacemCore.CustomElementUtils.findAncestorShell(this);
1586
+ shell.appendChild(dragDrop);
1587
+ dragDrop.addEventListener(pacemCore.UI.DragDropEventType.Init, this._dragInitHandler, false);
1588
+ dragDrop.addEventListener(pacemCore.UI.DragDropEventType.Drag, this._draggingHandler, false);
1589
+ dragDrop.addEventListener(pacemCore.UI.DragDropEventType.End, this._dragEndHandler, false);
1590
+ }
1591
+ disconnectedCallback() {
1592
+ const dragger = this.#dragger;
1593
+ if (!pacemCore.Utils.isNull(dragger)) {
1594
+ dragger.removeEventListener(pacemCore.UI.DragDropEventType.Init, this._dragInitHandler, false);
1595
+ dragger.removeEventListener(pacemCore.UI.DragDropEventType.Drag, this._draggingHandler, false);
1596
+ dragger.removeEventListener(pacemCore.UI.DragDropEventType.End, this._dragEndHandler, false);
1597
+ dragger.remove();
1598
+ }
1599
+ super.disconnectedCallback();
1600
+ }
1601
+ invalidateSize(scene, size) {
1602
+ const scenes = this._scenes;
1603
+ if (!pacemCore.Utils.isNull(scene) && !pacemCore.Utils.isNullOrEmpty(size)) {
1604
+ if (scenes.has(scene)) {
1605
+ const tuple = scenes.get(scene), ctx = tuple.context;
1606
+ ctx.canvas.width = size.width;
1607
+ ctx.canvas.height = size.height;
1608
+ const offset = tuple.offset = pacemCore.Utils.offsetRect(ctx.canvas);
1609
+ // transform matrix
1610
+ const stage = { x: 0, y: 0, width: size.width, height: size.height }, aspectRatio = scene.aspectRatio, viewbox = scene.viewbox;
1611
+ if (AdapterUtils.isValidViewbox(viewbox)) {
1612
+ // defaults to the equivalent of SVG's xMidYMid meet
1613
+ let mode = 'contain', align = 'center', valign = 'middle';
1614
+ if (typeof aspectRatio === 'object') {
1615
+ mode = aspectRatio.slice ? 'cover' : 'contain';
1616
+ switch (aspectRatio.x) {
1617
+ case 'min':
1618
+ align = 'left';
1619
+ break;
1620
+ case 'max':
1621
+ align = 'right';
1622
+ break;
1623
+ }
1624
+ switch (aspectRatio.y) {
1625
+ case 'min':
1626
+ valign = 'top';
1627
+ break;
1628
+ case 'max':
1629
+ valign = 'bottom';
1630
+ break;
1631
+ }
1632
+ }
1633
+ // mimic svg viewbox
1634
+ const mscale = pacemFoundation.Rect.findTransform({ x: 0, y: 0, width: viewbox.width, height: viewbox.height }, stage, mode, align, valign);
1635
+ const m = pacemFoundation.Matrix2D.translate(mscale, { x: -mscale.a * viewbox.x, y: -mscale.a * viewbox.y });
1636
+ tuple.transformMatrix = m;
1637
+ tuple.screenInverseMatrix = this._getScreenInverseMatrix(m, offset);
1638
+ }
1639
+ else {
1640
+ tuple.transformMatrix = pacemFoundation.Matrix2D.identity;
1641
+ }
1642
+ }
1643
+ }
1644
+ this._requestDraw(scene);
1645
+ }
1646
+ getHitTarget(stage) {
1647
+ const target = this._hitTarget;
1648
+ if (!pacemCore.Utils.isNull(target) && target.stage === stage) {
1649
+ return target;
1650
+ }
1651
+ return null;
1652
+ }
1653
+ initialize(scene) {
1654
+ if (pacemCore.Utils.isNull(scene)) {
1655
+ throw 'Provided scene is null or undefined.';
1656
+ }
1657
+ const scenes = this._scenes;
1658
+ const dragger = this.#dragger;
1659
+ // already in the store?
1660
+ if (scenes.has(scene)) {
1661
+ const canvas = scenes.get(scene).context.canvas;
1662
+ if (!pacemCore.Utils.isNull(dragger)) {
1663
+ dragger.register(canvas);
1664
+ }
1665
+ return canvas;
1666
+ }
1667
+ const stage = scene.stage;
1668
+ // empty stage DOM
1669
+ stage.innerHTML = '';
1670
+ const canvas = document.createElement('canvas');
1671
+ canvas.setAttribute('part', 'stage');
1672
+ SETVAR$1(canvas, CANVAS_SCENE_VAR, scene);
1673
+ const context = canvas.getContext('2d');
1674
+ canvas.addEventListener('mousemove', this._mousemoveHandler, false);
1675
+ canvas.addEventListener('mouseleave', this._mouseleaveHandler, false);
1676
+ canvas.addEventListener('touchstart', this._mouseDownUpHandler, { passive: true });
1677
+ canvas.addEventListener('touchmove', this._mouseDownUpHandler, { passive: true });
1678
+ canvas.addEventListener('touchend', this._mouseDownUpHandler, { passive: true });
1679
+ canvas.addEventListener('click', this._mouseDownUpHandler, false);
1680
+ canvas.addEventListener('mousedown', this._mouseDownUpHandler, false);
1681
+ canvas.addEventListener('mouseup', this._mouseDownUpHandler, false);
1682
+ stage.appendChild(canvas);
1683
+ scenes.set(scene, { context, transformMatrix: pacemFoundation.Matrix2D.identity, offset: pacemCore.Utils.offsetRect(canvas), screenInverseMatrix: pacemFoundation.Matrix2D.identity });
1684
+ if (!pacemCore.Utils.isNull(dragger)) {
1685
+ dragger.register(canvas);
1686
+ }
1687
+ return canvas;
1688
+ }
1689
+ dispose(scene) {
1690
+ const scenes = this._scenes;
1691
+ if (scenes.has(scene)) {
1692
+ var tuple = scenes.get(scene), context = tuple.context, canvas = context.canvas;
1693
+ const dragger = this.#dragger;
1694
+ if (!pacemCore.Utils.isNull(dragger)) {
1695
+ dragger.unregister(canvas);
1696
+ }
1697
+ canvas.removeEventListener('click', this._mouseDownUpHandler, false);
1698
+ canvas.removeEventListener('touchend', this._mouseDownUpHandler, false);
1699
+ canvas.removeEventListener('mousedown', this._mouseDownUpHandler, false);
1700
+ canvas.removeEventListener('mouseup', this._mouseDownUpHandler, false);
1701
+ // canvas.removeEventListener('touchmove', this._mouseDownUpHandler);
1702
+ canvas.removeEventListener('touchstart', this._mouseDownUpHandler);
1703
+ canvas.removeEventListener('mouseleave', this._mouseleaveHandler, false);
1704
+ canvas.removeEventListener('mousemove', this._mousemoveHandler, false);
1705
+ // remove
1706
+ canvas.remove();
1707
+ scenes.delete(scene);
1708
+ }
1709
+ }
1710
+ _requestDraw(scene) {
1711
+ const handles = this._handles;
1712
+ if (handles.has(scene)) {
1713
+ cancelAnimationFrame(handles.get(scene));
1714
+ }
1715
+ const throttle = () => {
1716
+ this.draw(scene);
1717
+ return requestAnimationFrame(() => { });
1718
+ };
1719
+ handles.set(scene, throttle());
1720
+ }
1721
+ #canvasCssStyle;
1722
+ draw(scene) {
1723
+ const scenes = this._scenes, handles = this._handles;
1724
+ if (!pacemCore.Utils.isNull(scene)) {
1725
+ if (scene.adapter !== this) {
1726
+ // not a pertinent stage anymore
1727
+ if (scenes.has(scene)) {
1728
+ scenes.delete(scene);
1729
+ handles.get(scene);
1730
+ }
1731
+ return;
1732
+ }
1733
+ if (!scenes.has(scene)) {
1734
+ // forgiving behavior (call initialize() if it's the case)
1735
+ this.initialize(scene);
1736
+ return;
1737
+ }
1738
+ if (handles.has(scene)) {
1739
+ // already in the drawing loop, reset
1740
+ cancelAnimationFrame(handles.get(scene));
1741
+ }
1742
+ const formerHitTarget = this._hitTarget;
1743
+ const items = scene.datasource || [];
1744
+ // reset hit target
1745
+ this._hitTarget = null;
1746
+ // clear stage
1747
+ const tuple = scenes.get(scene), context = tuple.context, canvas = context.canvas;
1748
+ this.#canvasCssStyle = getComputedStyle(canvas);
1749
+ context.resetTransform();
1750
+ context.clearRect(0, 0, canvas.width, canvas.height);
1751
+ // viewbox
1752
+ const m = tuple.transformMatrix;
1753
+ context.setTransform(m);
1754
+ // hit test
1755
+ const pointer = this._pointer, offset = tuple.offset, point = Number.isNaN(pointer.page.x) || Number.isNaN(pointer.page.y) ? null : { x: pointer.page.x - offset.x, y: pointer.page.y - offset.y };
1756
+ // draw recursively
1757
+ for (let drawable of items) {
1758
+ this._draw(scene, context, drawable, { transformMatrix: m }, point);
1759
+ }
1760
+ // check hit target
1761
+ const currentHitTarget = this._hitTarget;
1762
+ if (currentHitTarget != formerHitTarget) {
1763
+ if (!pacemCore.Utils.isNull(formerHitTarget)) {
1764
+ if (formerHitTarget instanceof Element) {
1765
+ formerHitTarget.dispatchEvent(new DrawableEvent('out', formerHitTarget, this._scopeEvent, m));
1766
+ }
1767
+ scene.dispatchEvent(new DrawableEvent('itemout', formerHitTarget, this._scopeEvent, m));
1768
+ }
1769
+ if (!pacemCore.Utils.isNull(currentHitTarget)) {
1770
+ if (currentHitTarget instanceof Element) {
1771
+ currentHitTarget.dispatchEvent(new DrawableEvent('over', currentHitTarget, this._scopeEvent, m));
1772
+ }
1773
+ scene.dispatchEvent(new DrawableEvent('itemover', currentHitTarget, this._scopeEvent, m));
1774
+ }
1775
+ }
1776
+ // do not loop
1777
+ // this._requestDraw(scene);
1778
+ }
1779
+ }
1780
+ _draw(scene, ctx, item, state, point) {
1781
+ item.stage ??= scene;
1782
+ if (isDrawable(item)) {
1783
+ if (item.hide) {
1784
+ return;
1785
+ }
1786
+ }
1787
+ // store parent matrix value for dragging purposes
1788
+ if (isUiObject(item) && item.draggable && !item.hide && !item.inert) {
1789
+ SETVAR$1(item, PARENT_MATRIX_VAR, ctx.getTransform().inverse());
1790
+ }
1791
+ let t;
1792
+ if (isUiObject(item)) {
1793
+ t = item.transformMatrix;
1794
+ if (!pacemCore.Utils.isNull(t) && !pacemFoundation.Matrix2D.isIdentity(t)) {
1795
+ ctx.transform(t.a, t.b, t.c, t.d, t.e, t.f);
1796
+ }
1797
+ }
1798
+ let contextPresentationState = state;
1799
+ if (isPresentationObject(item)) {
1800
+ //const stateWithWorldTransformMatrix = Utils.extend({}, state, { transformMatrix: ctx.getTransform() });
1801
+ contextPresentationState = PresentationState.combine(item, state, ctx.getTransform());
1802
+ // set presentation state
1803
+ this._setPresentationState(ctx, contextPresentationState);
1804
+ }
1805
+ if (isShape(item) || item instanceof ShapeElement) {
1806
+ this._drawShape(ctx, item, point);
1807
+ }
1808
+ else if (isText(item) || item instanceof PacemTextElement) {
1809
+ this._drawText(ctx, item, point);
1810
+ }
1811
+ else if (isImage(item) || item instanceof PacemImageElement) {
1812
+ this._drawImage(ctx, item, point);
1813
+ }
1814
+ else if (isGroup(item) || item instanceof PacemGroupElement) {
1815
+ for (let child of item.childDrawables || []) {
1816
+ this._draw(scene, ctx, child, contextPresentationState, point);
1817
+ }
1818
+ }
1819
+ // store global matrix value for debugging purposes
1820
+ if (isUiObject(item) && item.draggable && !item.hide && !item.inert) {
1821
+ SETVAR$1(item, WORLD_MATRIX_VAR, ctx.getTransform().inverse());
1822
+ }
1823
+ // reset presentation state
1824
+ this._setPresentationState(ctx, state);
1825
+ }
1826
+ _setPresentationState(ctx, item) {
1827
+ ctx.setTransform(item.transformMatrix);
1828
+ if (!pacemCore.Utils.isNullOrEmpty(item.stroke) && !isNone(item.stroke)) {
1829
+ ctx.strokeStyle = item.stroke;
1830
+ }
1831
+ else {
1832
+ ctx.strokeStyle = 'transparent';
1833
+ }
1834
+ if (!pacemCore.Utils.isNullOrEmpty(item.lineWidth)) {
1835
+ ctx.lineWidth = item.lineWidth;
1836
+ }
1837
+ else {
1838
+ ctx.lineWidth = 0;
1839
+ }
1840
+ if (!pacemCore.Utils.isNullOrEmpty(item.dashArray)) {
1841
+ ctx.setLineDash(item.dashArray);
1842
+ }
1843
+ else {
1844
+ ctx.setLineDash([]);
1845
+ }
1846
+ if (!pacemCore.Utils.isNullOrEmpty(item.lineCap)) {
1847
+ ctx.lineCap = item.lineCap;
1848
+ }
1849
+ else {
1850
+ ctx.lineCap = 'butt';
1851
+ }
1852
+ if (!pacemCore.Utils.isNullOrEmpty(item.lineJoin)) {
1853
+ ctx.lineJoin = item.lineJoin;
1854
+ }
1855
+ else {
1856
+ ctx.lineJoin = 'miter';
1857
+ }
1858
+ if (typeof item.fill === 'object' && !pacemCore.Utils.isNullOrEmpty(item.fill)) {
1859
+ const { stops } = item.fill;
1860
+ let gradient;
1861
+ if (isLinearGradient(item.fill)) {
1862
+ // linear gradient
1863
+ const { start, end } = item.fill;
1864
+ gradient = ctx.createLinearGradient(start.x, start.y, end.x, end.y);
1865
+ }
1866
+ else if (isRadialGradient(item.fill)) {
1867
+ // radial gradient
1868
+ const { center, radius } = item.fill;
1869
+ gradient = ctx.createRadialGradient(center.x, center.y, radius, center.x, center.y, radius);
1870
+ }
1871
+ else {
1872
+ throw new Error('Unmanaged gradient type.');
1873
+ }
1874
+ for (let stop of stops) {
1875
+ gradient.addColorStop(stop.offset, stop.color);
1876
+ }
1877
+ ctx.fillStyle = gradient;
1878
+ }
1879
+ else if (!pacemCore.Utils.isNullOrEmpty(item.fill) && typeof item.fill === 'string' && !isNone(item.fill)) {
1880
+ ctx.fillStyle = item.fill;
1881
+ }
1882
+ else {
1883
+ ctx.fillStyle = 'transparent';
1884
+ }
1885
+ if (!pacemCore.Utils.isNullOrEmpty(item.opacity)) {
1886
+ ctx.globalAlpha = item.opacity;
1887
+ }
1888
+ else {
1889
+ ctx.globalAlpha = 1.0;
1890
+ }
1891
+ }
1892
+ _drawImage(ctx, item, point) {
1893
+ const CANVAS_IMAGESOURCE_VAR = 'pacem:2d-canvas-imagesrc';
1894
+ let img = GETVAR$1(item, CANVAS_IMAGESOURCE_VAR);
1895
+ const imgLoadHandler = () => {
1896
+ let dw = img.naturalWidth, dh = img.naturalHeight, w = item.width, h = item.height;
1897
+ if (w > 0 && h > 0) ;
1898
+ else if (w > 0) {
1899
+ h = dh * w / dw;
1900
+ }
1901
+ else if (h > 0) {
1902
+ w = dw * h / dh;
1903
+ }
1904
+ else {
1905
+ w = dw;
1906
+ h = dh;
1907
+ }
1908
+ if (!this._dragging
1909
+ && !item.inert /* is hit-test visible? */
1910
+ && !pacemCore.Utils.isNull(point)) {
1911
+ const path2D = new Path2D(`M ${item.x} ${item.y} h ${w} v ${h} H ${item.x} Z`);
1912
+ if (ctx.isPointInPath(path2D, point.x, point.y)) {
1913
+ // overwrite current hit-target (last one wins)
1914
+ this._hitTarget = item;
1915
+ }
1916
+ }
1917
+ ctx.globalAlpha = fallback$1(item.opacity, 1);
1918
+ ctx.drawImage(img, item.x, item.y, w, h);
1919
+ };
1920
+ if (pacemCore.Utils.isNull(img)) {
1921
+ img = new Image();
1922
+ img.src = item.src;
1923
+ img.onload = () => {
1924
+ SETVAR$1(item, CANVAS_IMAGESOURCE_VAR, img);
1925
+ imgLoadHandler();
1926
+ };
1927
+ }
1928
+ else {
1929
+ imgLoadHandler();
1930
+ }
1931
+ }
1932
+ _drawText(ctx, item, point) {
1933
+ const defaults = this.DefaultShapeValues;
1934
+ const color = ctx.fillStyle = fallback$1(item.color, defaults.stroke);
1935
+ ctx.getTransform(); const fontSize = item.fontSize > 0 ? `${item.fontSize}px` : this.#canvasCssStyle.fontSize, fontStyle = item.fontStyle || this.#canvasCssStyle.fontStyle, fontWeight = item.fontWeight || this.#canvasCssStyle.fontWeight;
1936
+ ctx.font = `${fontStyle} ${fontWeight} ${fontSize} ${(item.fontFamily ?? this.#canvasCssStyle.fontFamily)}`;
1937
+ ctx.textAlign = item.textAnchor === 'middle' ? 'center' : item.textAnchor;
1938
+ ctx.fillText(item.text, item.anchor.x, item.anchor.y);
1939
+ ctx.globalAlpha = fallback$1(item.opacity, 1);
1940
+ const hasColor = !isNone(color);
1941
+ if (!this._dragging
1942
+ && !item.inert /* is hit-test visible? */
1943
+ && !pacemCore.Utils.isNull(point)) {
1944
+ const bbox = ctx.measureText(item.text);
1945
+ const width = bbox.width, height = bbox.actualBoundingBoxAscent + bbox.actualBoundingBoxDescent, x = item.anchor.x - bbox.actualBoundingBoxLeft, y = item.anchor.y - bbox.actualBoundingBoxAscent;
1946
+ const path2D = new Path2D(`M ${x} ${y} h ${width} v ${height} H ${x} z`);
1947
+ if (hasColor && ctx.isPointInPath(path2D, point.x, point.y)) {
1948
+ // overwrite current hit-target (last one wins)
1949
+ this._hitTarget = item;
1950
+ }
1951
+ }
1952
+ }
1953
+ _drawShape(ctx, item, point) {
1954
+ if (pacemCore.Utils.isNullOrEmpty(item?.pathData)) {
1955
+ return;
1956
+ }
1957
+ ctx.beginPath();
1958
+ // Path2D
1959
+ const hasFill = typeof ctx.fillStyle !== 'string' || !isNone(ctx.fillStyle), hasStroke = typeof ctx.strokeStyle !== 'string' || !isNone(ctx.strokeStyle);
1960
+ var path2D = new Path2D(item.pathData);
1961
+ if (!this._dragging
1962
+ && !item.inert /* is hit-test visible? */
1963
+ && !pacemCore.Utils.isNull(point)) {
1964
+ if ((hasFill && ctx.isPointInPath(path2D, point.x, point.y))
1965
+ || (hasStroke && ctx.isPointInStroke(path2D, point.x, point.y))) {
1966
+ // overwrite current hit-target (last one wins)
1967
+ this._hitTarget = item;
1968
+ }
1969
+ }
1970
+ if (hasStroke) {
1971
+ ctx.stroke(path2D);
1972
+ }
1973
+ if (hasFill) {
1974
+ ctx.fill(path2D);
1975
+ }
1976
+ const hasEnoughVertices = !pacemCore.Utils.isNullOrEmpty(item.vertices) && item.vertices.length > 1, hasMarkerEnd = !pacemCore.Utils.isNull(item.markerEnd), hasMarkerStart = !pacemCore.Utils.isNull(item.markerStart), hasMarkerMid = !pacemCore.Utils.isNull(item.markerMid);
1977
+ if (hasMarkerEnd || hasMarkerMid || hasMarkerStart) {
1978
+ if (!hasEnoughVertices) {
1979
+ this.log(pacemCore.Logging.LogLevel.Warn, "Not enough vertices were explicited in order to make markers renderable.");
1980
+ }
1981
+ }
1982
+ // WebGL: we can render markers only if vertices are explicit
1983
+ if (hasEnoughVertices) {
1984
+ const matrix = ctx.getTransform();
1985
+ if (hasMarkerStart) {
1986
+ const marker = item.markerEnd, from = item.vertices[1], to = item.vertices[0];
1987
+ const orientation = Math.atan2(to.y - from.y, to.x - from.x);
1988
+ this._drawMarker(ctx, marker, to, orientation);
1989
+ }
1990
+ if (hasMarkerMid) {
1991
+ const marker = item.markerEnd;
1992
+ for (let j = 1; j < item.vertices.length - 1; j++) {
1993
+ // reset transform, just in case
1994
+ ctx.setTransform(matrix);
1995
+ const from = item.vertices[j], to = item.vertices[j + 1];
1996
+ const orientation = Math.atan2(to.y - from.y, to.x - from.x);
1997
+ this._drawMarker(ctx, marker, to, orientation);
1998
+ }
1999
+ }
2000
+ if (hasMarkerEnd) {
2001
+ // reset transform, just in case
2002
+ ctx.setTransform(matrix);
2003
+ const marker = item.markerEnd, from = item.vertices[item.vertices.length - 2], to = item.vertices[item.vertices.length - 1];
2004
+ const orientation = Math.atan2(to.y - from.y, to.x - from.x);
2005
+ this._drawMarker(ctx, marker, to, orientation);
2006
+ }
2007
+ }
2008
+ }
2009
+ _drawMarker(ctx, marker, point, orientation) {
2010
+ const defaults = this.DefaultShapeValues;
2011
+ const refX = marker.ref?.x || 0, refY = marker.ref?.y || 0;
2012
+ const width = (marker.width || 1) * ctx.lineWidth, height = (marker.width || 1) * ctx.lineWidth;
2013
+ let viewbox = marker.viewbox, stage = { x: 0, y: 0, width: width, height: height };
2014
+ if (pacemCore.Utils.isNull(viewbox)) {
2015
+ viewbox = stage;
2016
+ }
2017
+ // prepare
2018
+ const mscale = { a: stage.width / viewbox.width, d: stage.height / viewbox.height }; // Rect.findTransform({ x: 0, y: 0, width: viewbox.width, height: viewbox.height }, stage, 'stretch', 'left', 'top');
2019
+ // execute
2020
+ ctx.translate(point.x, point.y);
2021
+ ctx.rotate(orientation);
2022
+ ctx.scale(mscale.a, mscale.d);
2023
+ ctx.translate(-refX, -refY);
2024
+ ctx.fillStyle = fallback$1(marker.fill, defaults.fill);
2025
+ ctx.strokeStyle = fallback$1(marker.stroke, defaults.stroke);
2026
+ // Path2D
2027
+ const hasMarkerFill = !isNone(marker.fill), hasMarkerStroke = !isNone(marker.stroke);
2028
+ var markerPath2D = new Path2D(marker.pathData);
2029
+ if (hasMarkerFill) {
2030
+ ctx.fill(markerPath2D);
2031
+ }
2032
+ if (hasMarkerStroke) {
2033
+ ctx.stroke(markerPath2D);
2034
+ }
2035
+ }
2036
+ };
2037
+ PacemCanvasAdapterElement = __decorate$1([
2038
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME + '-canvas-adapter' })
2039
+ ], PacemCanvasAdapterElement);
2040
+
2041
+ var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
2042
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2043
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2044
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2045
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2046
+ };
2047
+ //namespace Pacem.Components.Drawing {
2048
+ const SVG_NS = 'http://www.w3.org/2000/svg', DRAWABLE_VAR = 'pacem:2-svg-drawable', STAGE_VAR = 'pacem:2d-svg-stage', GETVAR = pacemCore.CustomElementUtils.getAttachedPropertyValue, SETVAR = pacemCore.CustomElementUtils.setAttachedPropertyValue, DELVAR = pacemCore.CustomElementUtils.deleteAttachedPropertyValue;
2049
+ function fallback(v, f) {
2050
+ return pacemCore.Utils.isNull(v) ? f : v;
2051
+ }
2052
+ function replaceChildAt(parent, newChild, targetIndex) {
2053
+ if (targetIndex >= parent.children.length) {
2054
+ parent.appendChild(newChild);
2055
+ return null;
2056
+ }
2057
+ else {
2058
+ return parent.replaceChild(newChild, parent.children.item(targetIndex));
2059
+ }
2060
+ }
2061
+ let PacemSvgAdapterElement = class PacemSvgAdapterElement extends Pacem2DAdapterElement {
2062
+ constructor() {
2063
+ super(...arguments);
2064
+ this._hitTarget = null;
2065
+ this._dragInitHandler = (evt) => {
2066
+ const args = evt.detail, el = args.element, drawable = GETVAR(el, DRAWABLE_VAR), stageTransformMatrix = drawable.stage.transformMatrix, initialMatrix = drawable.transformMatrix ?? pacemFoundation.Matrix2D.identity;
2067
+ args.data = {
2068
+ stageTransformMatrix, item: drawable,
2069
+ initialTransformMatrix: initialMatrix
2070
+ };
2071
+ const reject = AdapterUtils.itemDispatch(drawable, evt, { x: 0, y: 0 });
2072
+ if (reject) {
2073
+ // reject dragging
2074
+ evt.preventDefault();
2075
+ }
2076
+ };
2077
+ this._draggingHandler = (evt) => {
2078
+ pacemCore.avoidHandler(evt);
2079
+ this.#dragging = true;
2080
+ const el = evt.detail.element;
2081
+ const data = evt.detail.data;
2082
+ const args = evt.detail;
2083
+ const screenOffset = { x: (args.currentPosition.x - args.origin.x) * data.stageTransformMatrix.a, y: (args.currentPosition.y - args.origin.y) * data.stageTransformMatrix.d };
2084
+ const offset = {
2085
+ x: screenOffset.x + data.initialTransformMatrix.e,
2086
+ y: screenOffset.y + data.initialTransformMatrix.f
2087
+ },
2088
+ // this is not correct when item or any of its parents have been rotated!
2089
+ stageOffset = {
2090
+ x: screenOffset.x + data.stageTransformMatrix.e,
2091
+ y: screenOffset.y + data.stageTransformMatrix.f
2092
+ };
2093
+ //console.log(`current pos: ${args.currentPosition.x},${args.currentPosition.y}`);
2094
+ //console.log(`origin pos: ${args.origin.x},${args.origin.y}`);
2095
+ //console.log(`offset: ${offset.x},${offset.y}`);
2096
+ //console.log(data.stageTransformMatrix);
2097
+ //console.log(el.style.transform); console.log(data.initialTransformMatrix);
2098
+ const rejected = AdapterUtils.itemDispatch(data.item, evt, stageOffset);
2099
+ if (!rejected) {
2100
+ const init = data.initialTransformMatrix;
2101
+ el.style.transform = `matrix(${init.a},${init.b},${init.c},${init.d},${offset.x},${offset.y})`;
2102
+ }
2103
+ };
2104
+ this._dragEndHandler = (evt) => {
2105
+ this.#dragging = false;
2106
+ const args = evt.detail, el = args.element, data = args.data, transform = pacemCore.Utils.deserializeTransform(el.style);
2107
+ // store transform
2108
+ const offset = { x: transform.e, y: transform.f };
2109
+ if (data.item instanceof UiElement) {
2110
+ data.item.translateX = offset.x;
2111
+ data.item.translateY = offset.y;
2112
+ }
2113
+ else {
2114
+ const init = data.initialTransformMatrix, actual = { a: init.a, b: init.b, c: init.c, d: init.d, e: offset.x, f: offset.y };
2115
+ pacemCore.Utils.extend(data.item, { transformMatrix: actual });
2116
+ }
2117
+ el.style.transform = '';
2118
+ AdapterUtils.itemDispatch(data.item, evt, offset);
2119
+ };
2120
+ this._mouseleaveHandler = (evt) => {
2121
+ if (this.#dragging) {
2122
+ return;
2123
+ }
2124
+ const hitTarget = this._hitTarget;
2125
+ if (pacemCore.Utils.isNull(hitTarget)) {
2126
+ return;
2127
+ }
2128
+ this._hitTarget = null;
2129
+ if (!pacemCore.Utils.isNull(hitTarget)) {
2130
+ this.#dragger.unregister(this._items.get(hitTarget));
2131
+ AdapterUtils.itemDispatch(hitTarget, 'out', evt);
2132
+ }
2133
+ };
2134
+ this._mousemoveHandler = (evt) => {
2135
+ var pt = pacemCore.CustomEventUtils.getEventCoordinates(evt).client;
2136
+ if (!this.#dragging) {
2137
+ // not dragging around
2138
+ var d = null;
2139
+ const root = evt.target.getRootNode();
2140
+ root.elementsFromPoint(pt.x, pt.y).find(i => {
2141
+ d = GETVAR(i, DRAWABLE_VAR);
2142
+ return d && !d.inert;
2143
+ });
2144
+ var old = this._hitTarget, val = d;
2145
+ if (pacemCore.Utils.isNull(d && d.stage) || !this._scenes.has(d.stage) || d.inert) {
2146
+ val = null;
2147
+ }
2148
+ const hitTarget = this._hitTarget = val;
2149
+ if (val !== old) {
2150
+ if (!pacemCore.Utils.isNull(old)) {
2151
+ this.#dragger.unregister(this._items.get(old));
2152
+ AdapterUtils.itemDispatch(old, 'out', evt);
2153
+ }
2154
+ if (!pacemCore.Utils.isNull(val)) {
2155
+ if (val.draggable) {
2156
+ this.#dragger.register(this._items.get(val));
2157
+ }
2158
+ AdapterUtils.itemDispatch(val, 'over', evt);
2159
+ }
2160
+ }
2161
+ if (pacemCore.Utils.isNull(hitTarget)) {
2162
+ // dispatch only if no hit target
2163
+ const svg = evt.currentTarget;
2164
+ const stage = GETVAR(svg, STAGE_VAR);
2165
+ if (!pacemCore.Utils.isNull(stage)) {
2166
+ AdapterUtils.stageDispatch(stage, 'move', evt);
2167
+ }
2168
+ }
2169
+ }
2170
+ };
2171
+ this._mouseDownUpHandler = (evt) => {
2172
+ const svg = evt.currentTarget;
2173
+ if (svg instanceof SVGSVGElement) {
2174
+ const stage = GETVAR(svg, STAGE_VAR), hitTarget = this._hitTarget;
2175
+ const type = evt.type.replace(/^mouse/, '');
2176
+ const opts = getStageOptions(stage);
2177
+ if (pacemCore.CustomEventUtils.matchModifiers(evt, opts.clickModifiers)) {
2178
+ if (!pacemCore.Utils.isNull(hitTarget) && hitTarget.stage === stage) {
2179
+ AdapterUtils.itemDispatch(hitTarget, type, evt);
2180
+ }
2181
+ else {
2182
+ AdapterUtils.stageDispatch(stage, type, evt);
2183
+ }
2184
+ }
2185
+ }
2186
+ };
2187
+ this._scenes = new WeakMap();
2188
+ this._markers = new WeakMap();
2189
+ this._gradients = new WeakMap();
2190
+ this._items = new WeakMap();
2191
+ }
2192
+ snapshot(stage, background, type, quality) {
2193
+ if (this._scenes.has(stage)) {
2194
+ const svg = this._scenes.get(stage);
2195
+ return this.snapshotElement(svg, background, type, quality);
2196
+ }
2197
+ else {
2198
+ return Promise.resolve(null);
2199
+ }
2200
+ }
2201
+ getTransformMatrix(scene) {
2202
+ const scenes = this._scenes;
2203
+ if (scenes.has(scene)) {
2204
+ return scenes.get(scene).getScreenCTM().inverse();
2205
+ }
2206
+ return pacemFoundation.Matrix2D.identity;
2207
+ }
2208
+ #dragger;
2209
+ viewActivatedCallback() {
2210
+ super.viewActivatedCallback();
2211
+ const dragDrop = this.#dragger = document.createElement(pacemCore.P + '-drag-drop');
2212
+ dragDrop.mode = pacemCore.UI.DragDataMode.Self;
2213
+ // append
2214
+ const shell = pacemCore.CustomElementUtils.findAncestorShell(this);
2215
+ shell.appendChild(dragDrop);
2216
+ dragDrop.addEventListener(pacemCore.UI.DragDropEventType.Init, this._dragInitHandler, false);
2217
+ dragDrop.addEventListener(pacemCore.UI.DragDropEventType.Drag, this._draggingHandler, false);
2218
+ dragDrop.addEventListener(pacemCore.UI.DragDropEventType.End, this._dragEndHandler, false);
2219
+ }
2220
+ disconnectedCallback() {
2221
+ const dragger = this.#dragger;
2222
+ if (!pacemCore.Utils.isNull(dragger)) {
2223
+ dragger.removeEventListener(pacemCore.UI.DragDropEventType.Init, this._dragInitHandler, false);
2224
+ dragger.removeEventListener(pacemCore.UI.DragDropEventType.Drag, this._draggingHandler, false);
2225
+ dragger.removeEventListener(pacemCore.UI.DragDropEventType.End, this._dragEndHandler, false);
2226
+ dragger.remove();
2227
+ }
2228
+ super.disconnectedCallback();
2229
+ }
2230
+ invalidateSize(scene, size) {
2231
+ const scenes = this._scenes;
2232
+ if (!pacemCore.Utils.isNull(scene) && !pacemCore.Utils.isNullOrEmpty(size)) {
2233
+ if (scenes.has(scene)) {
2234
+ var svg = scenes.get(scene);
2235
+ svg.setAttribute('width', size.width + '');
2236
+ svg.setAttribute('height', size.height + '');
2237
+ const rect = scene.viewbox, aspectRatio = scene.aspectRatio;
2238
+ if (AdapterUtils.isValidViewbox(rect)) {
2239
+ svg.setAttribute('viewBox', `${rect.x} ${rect.y} ${rect.width} ${rect.height}`);
2240
+ }
2241
+ else {
2242
+ svg.removeAttribute('viewBox');
2243
+ }
2244
+ if (pacemCore.Utils.isNullOrEmpty(aspectRatio) || typeof aspectRatio === 'string') {
2245
+ svg.removeAttribute('preserveAspectRatio');
2246
+ }
2247
+ else {
2248
+ svg.setAttribute('preserveAspectRatio', `xM${aspectRatio.x.substring(1)}YM${aspectRatio.y.substring(1)} ${(aspectRatio.slice ? 'slice' : 'meet')}`);
2249
+ }
2250
+ }
2251
+ }
2252
+ }
2253
+ initialize(scene) {
2254
+ if (pacemCore.Utils.isNull(scene)) {
2255
+ throw 'Provided scene is null or undefined.';
2256
+ }
2257
+ const scenes = this._scenes;
2258
+ // already in the store?
2259
+ if (scenes.has(scene)) {
2260
+ return scenes.get(scene);
2261
+ }
2262
+ const stage = scene.stage;
2263
+ // empty stage DOM and clear dictionary
2264
+ stage.innerHTML = '';
2265
+ this._items = new WeakMap();
2266
+ var svg = document.createElementNS(SVG_NS, 'svg');
2267
+ svg.setAttribute('part', 'stage');
2268
+ SETVAR(svg, STAGE_VAR, scene);
2269
+ stage.appendChild(svg);
2270
+ scenes.set(scene, svg);
2271
+ svg.addEventListener('mousemove', this._mousemoveHandler, false);
2272
+ svg.addEventListener('click', this._mouseDownUpHandler, false);
2273
+ svg.addEventListener('mousedown', this._mouseDownUpHandler, false);
2274
+ svg.addEventListener('mouseup', this._mouseDownUpHandler, false);
2275
+ svg.addEventListener('mouseleave', this._mouseleaveHandler, false);
2276
+ // draw right away
2277
+ // this.draw(scene);
2278
+ return svg;
2279
+ }
2280
+ dispose(scene) {
2281
+ const scenes = this._scenes;
2282
+ if (scenes.has(scene)) {
2283
+ var svg = scenes.get(scene);
2284
+ svg.removeEventListener('mousemove', this._mousemoveHandler);
2285
+ svg.removeEventListener('click', this._mouseDownUpHandler);
2286
+ svg.removeEventListener('mousedown', this._mouseDownUpHandler);
2287
+ svg.removeEventListener('mouseup', this._mouseDownUpHandler);
2288
+ svg.removeEventListener('mouseleave', this._mouseleaveHandler);
2289
+ // remove
2290
+ DELVAR(svg, STAGE_VAR);
2291
+ svg.remove();
2292
+ scenes.delete(scene);
2293
+ }
2294
+ }
2295
+ getHitTarget(scene) {
2296
+ return this._hitTarget;
2297
+ }
2298
+ draw(scene, item, deepRedraw = false) {
2299
+ const scenes = this._scenes, dict = this._items;
2300
+ if (!pacemCore.Utils.isNull(scene)) {
2301
+ if (scene.adapter === this) {
2302
+ if (!scenes.has(scene)) {
2303
+ // forgiving behavior (call initialize() if it's the case)
2304
+ this.initialize(scene);
2305
+ }
2306
+ }
2307
+ else {
2308
+ if (scenes.has(scene)) {
2309
+ scenes.delete(scene);
2310
+ }
2311
+ return;
2312
+ }
2313
+ }
2314
+ else {
2315
+ return;
2316
+ }
2317
+ var items = scene.datasource, flow = true, parent = scenes.get(scene);
2318
+ // item provided?
2319
+ if (!pacemCore.Utils.isNull(item) && dict.has(item)) {
2320
+ items = [item];
2321
+ parent = dict.get(item).parentNode;
2322
+ flow = false;
2323
+ }
2324
+ if (flow) {
2325
+ // sweep everything, quick and dirty
2326
+ parent.innerHTML = '<defs></defs>';
2327
+ this._markers = new WeakMap();
2328
+ }
2329
+ this._draw(scene, parent, items || [], flow, deepRedraw);
2330
+ }
2331
+ #dragging;
2332
+ _hasItems(object) {
2333
+ return isGroup(object);
2334
+ }
2335
+ _disposeSvg(el) {
2336
+ if (!pacemCore.Utils.isNull(el)) {
2337
+ var drawable = GETVAR(el, DRAWABLE_VAR);
2338
+ DELVAR(el, DRAWABLE_VAR);
2339
+ this._items.delete(drawable);
2340
+ }
2341
+ }
2342
+ _draw(scene, parent, items, flow, deepRedraw) {
2343
+ const dict = this._items;
2344
+ // children counter
2345
+ let j = 0;
2346
+ if (parent.firstElementChild instanceof SVGDefsElement) {
2347
+ j++;
2348
+ }
2349
+ if (!pacemCore.Utils.isNullOrEmpty(items)) {
2350
+ for (let item of items) {
2351
+ item.stage ??= scene;
2352
+ let el;
2353
+ if (!dict.has(item)) {
2354
+ el = this._buildSVGElement(item);
2355
+ SETVAR(el, DRAWABLE_VAR, item);
2356
+ this._disposeSvg(replaceChildAt(parent, el, j));
2357
+ dict.set(item, el);
2358
+ }
2359
+ else {
2360
+ el = dict.get(item);
2361
+ if (el.parentNode !== parent) {
2362
+ this._disposeSvg(replaceChildAt(parent, el, j));
2363
+ }
2364
+ }
2365
+ if (isDrawable(item)) {
2366
+ if (item.hide) {
2367
+ el.setAttribute('display', 'none');
2368
+ }
2369
+ else {
2370
+ el.removeAttribute('display');
2371
+ }
2372
+ el.style.transform = '';
2373
+ }
2374
+ if (isShape(item)) {
2375
+ const path = el;
2376
+ path.setAttribute('d', fallback(item.pathData, 'M0,0'));
2377
+ // markers
2378
+ for (let { marker, suffix } of [{ marker: item.markerStart, suffix: 'start' }, { marker: item.markerEnd, suffix: 'end' }, { marker: item.markerMid, suffix: 'mid' }]) {
2379
+ if (marker) {
2380
+ const markerSvg = this._ensureMarker(parent, marker);
2381
+ path.setAttribute('marker-' + suffix, `url(#${markerSvg.id})`);
2382
+ }
2383
+ else {
2384
+ path.removeAttribute('marker-' + suffix);
2385
+ }
2386
+ }
2387
+ }
2388
+ else if (isText(item)) {
2389
+ const text = el;
2390
+ text.textContent = item.text;
2391
+ text.style.fill = pacemCore.Utils.isNullOrEmpty(item.color) ? '' : item.color;
2392
+ text.style.fontFamily = pacemCore.Utils.isNullOrEmpty(item.fontFamily) ? '' : item.fontFamily;
2393
+ //if (item.fontSize > 0) {
2394
+ // text.setAttribute('font-size', item.fontSize.toString());
2395
+ //} else {
2396
+ // text.removeAttribute('font-size');
2397
+ //}
2398
+ text.style.fontSize = pacemCore.Utils.isNull(item.fontSize) ? '' : item.fontSize + 'px';
2399
+ if (!pacemCore.Utils.isNullOrEmpty(item.fontWeight)) {
2400
+ text.style.fontWeight = item.fontWeight;
2401
+ }
2402
+ if (!pacemCore.Utils.isNullOrEmpty(item.fontStyle)) {
2403
+ text.style.fontStyle = item.fontStyle;
2404
+ }
2405
+ text.setAttribute('text-anchor', fallback(item.textAnchor, 'start'));
2406
+ if (!pacemCore.Utils.isNull(item.anchor)) {
2407
+ text.setAttribute('x', item.anchor.x.toString());
2408
+ text.setAttribute('y', item.anchor.y.toString());
2409
+ }
2410
+ else {
2411
+ text.removeAttribute('x');
2412
+ text.removeAttribute('y');
2413
+ }
2414
+ }
2415
+ else if (isImage(item)) {
2416
+ const img = el;
2417
+ img.setAttribute('href', item.src);
2418
+ img.setAttribute('preserveAspectRatio', 'none');
2419
+ if (item.width > 0) {
2420
+ img.setAttribute('width', '' + item.width);
2421
+ }
2422
+ else {
2423
+ img.removeAttribute('width');
2424
+ }
2425
+ if (item.height > 0) {
2426
+ img.setAttribute('height', '' + item.height);
2427
+ }
2428
+ else {
2429
+ img.removeAttribute('height');
2430
+ }
2431
+ if (!pacemCore.Utils.isNull(item.x)) {
2432
+ img.setAttribute('x', '' + item.x);
2433
+ }
2434
+ else {
2435
+ img.removeAttribute('x');
2436
+ }
2437
+ if (!pacemCore.Utils.isNull(item.y)) {
2438
+ img.setAttribute('y', '' + item.y);
2439
+ }
2440
+ else {
2441
+ img.removeAttribute('y');
2442
+ }
2443
+ }
2444
+ if (isUiObject(item)) {
2445
+ const t = item.transformMatrix;
2446
+ if (pacemCore.Utils.isNull(t) || pacemFoundation.Matrix2D.isIdentity(t)) {
2447
+ el.removeAttribute('transform');
2448
+ }
2449
+ else {
2450
+ el.setAttribute('transform', `matrix(${t.a} ${t.b} ${t.c} ${t.d} ${t.e} ${t.f})`);
2451
+ }
2452
+ const opacity = fallback(item.opacity, 1);
2453
+ if (opacity === 1) {
2454
+ el.removeAttribute('opacity');
2455
+ }
2456
+ else {
2457
+ el.setAttribute('opacity', '' + opacity);
2458
+ }
2459
+ }
2460
+ if (isPresentationObject(item)) {
2461
+ if (pacemCore.Utils.isNullOrEmpty(item.fill)) {
2462
+ el.removeAttribute('fill');
2463
+ }
2464
+ else if (typeof item.fill === 'string') {
2465
+ el.setAttribute('fill', item.fill);
2466
+ }
2467
+ else {
2468
+ const grad = this._ensureGradient(parent, item.fill);
2469
+ el.setAttribute('fill', `url(#${grad.id})`);
2470
+ }
2471
+ if (pacemCore.Utils.isNullOrEmpty(item.stroke)) {
2472
+ el.removeAttribute('stroke');
2473
+ }
2474
+ else {
2475
+ el.setAttribute('stroke', item.stroke);
2476
+ }
2477
+ if (pacemCore.Utils.isNullOrEmpty(item.dashArray)) {
2478
+ el.removeAttribute('stroke-dasharray');
2479
+ }
2480
+ else {
2481
+ el.setAttribute('stroke-dasharray', item.dashArray.join(' '));
2482
+ }
2483
+ if (pacemCore.Utils.isNullOrEmpty(item.lineCap)) {
2484
+ el.removeAttribute('stroke-linecap');
2485
+ }
2486
+ else {
2487
+ el.setAttribute('stroke-linecap', item.lineCap);
2488
+ }
2489
+ if (pacemCore.Utils.isNullOrEmpty(item.lineJoin)) {
2490
+ el.removeAttribute('stroke-linejoin');
2491
+ }
2492
+ else {
2493
+ el.setAttribute('stroke-linejoin', item.lineJoin);
2494
+ }
2495
+ if (pacemCore.Utils.isNullOrEmpty(item.lineWidth)) {
2496
+ el.removeAttribute('stroke-width');
2497
+ }
2498
+ else {
2499
+ el.setAttribute('stroke-width', '' + item.lineWidth);
2500
+ }
2501
+ //let css = '';
2502
+ //if (!Utils.isNullOrEmpty(item.dashArray)) {
2503
+ // css += `stroke-dasharray: ${item.dashArray.join(',')};`;
2504
+ //}
2505
+ //if (!Utils.isNullOrEmpty(item.lineCap)) {
2506
+ // css += `stroke-linecap: ${item.lineCap};`;
2507
+ //}
2508
+ //if (!Utils.isNullOrEmpty(item.lineJoin)) {
2509
+ // css += `stroke-linejoin: ${item.lineJoin};`;
2510
+ //}
2511
+ //el.style.cssText = css;
2512
+ //el.setAttribute('stroke-width', '' + fallback(item.lineWidth, defaults.lineWidth));
2513
+ }
2514
+ // hit test visibility
2515
+ if (item.inert) {
2516
+ el.style.pointerEvents = 'none';
2517
+ }
2518
+ else {
2519
+ el.style.pointerEvents = '';
2520
+ }
2521
+ if ((flow || deepRedraw) && this._hasItems(item)) {
2522
+ // recursion
2523
+ this._draw(scene, el, item.childDrawables, true, deepRedraw);
2524
+ }
2525
+ j++;
2526
+ }
2527
+ }
2528
+ if (flow) {
2529
+ // remove exceeding children (except defs)
2530
+ for (let k = parent.children.length - 1; k >= j; k--) {
2531
+ const el = parent.children.item(k);
2532
+ this._disposeSvg(el);
2533
+ el.remove();
2534
+ }
2535
+ }
2536
+ }
2537
+ _buildSVGElement(item) {
2538
+ if (isShape(item) || item instanceof ShapeElement) {
2539
+ return document.createElementNS(SVG_NS, 'path');
2540
+ }
2541
+ if (isText(item) || item instanceof PacemTextElement) {
2542
+ return document.createElementNS(SVG_NS, 'text');
2543
+ }
2544
+ if (isImage(item) || item instanceof PacemImageElement) {
2545
+ return document.createElementNS(SVG_NS, 'image');
2546
+ }
2547
+ return document.createElementNS(SVG_NS, 'g');
2548
+ }
2549
+ _ensureGradient(parent, gradient) {
2550
+ const store = this._gradients;
2551
+ if (!store.has(parent)) {
2552
+ store.set(parent, new WeakMap());
2553
+ }
2554
+ const map = store.get(parent);
2555
+ // linear or radial?
2556
+ const isLinear = isLinearGradient(gradient), isRadial = isRadialGradient(gradient);
2557
+ if (map.has(gradient)) {
2558
+ const current = map.get(gradient);
2559
+ if ((isLinear && current instanceof SVGLinearGradientElement)
2560
+ || (isRadial && current instanceof SVGRadialGradientElement)) {
2561
+ // remove from DOM
2562
+ current.remove();
2563
+ // remove from memoizer
2564
+ map.delete(gradient);
2565
+ }
2566
+ }
2567
+ if (!map.has(gradient)) {
2568
+ // <defs>
2569
+ let defsContainer = parent;
2570
+ let defs;
2571
+ while (pacemCore.Utils.isNull(defs = defsContainer.querySelector(':scope > defs'))) {
2572
+ const parent1 = defsContainer.parentElement;
2573
+ if (parent1 instanceof SVGElement) {
2574
+ defsContainer = parent1;
2575
+ }
2576
+ else {
2577
+ break;
2578
+ }
2579
+ }
2580
+ if (pacemCore.Utils.isNull(defs)) {
2581
+ throw new Error('Must provide a <defs> element.');
2582
+ }
2583
+ var gradientSvg = null;
2584
+ if (isLinear) {
2585
+ // create linear gradient node
2586
+ gradientSvg = document.createElementNS(SVG_NS, 'linearGradient');
2587
+ }
2588
+ else if (isRadialGradient(gradient)) {
2589
+ // create radial gradient node
2590
+ gradientSvg = document.createElementNS(SVG_NS, 'radialGradient');
2591
+ }
2592
+ else {
2593
+ throw new Error('Unmanaged gradient type.');
2594
+ }
2595
+ gradientSvg.setAttribute('gradientUnits', 'userSpaceOnUse');
2596
+ gradientSvg.setAttribute('id', `grad-${pacemCore.Utils.uniqueCode()}`);
2597
+ defs.appendChild(gradientSvg);
2598
+ map.set(gradient, gradientSvg);
2599
+ }
2600
+ const retval = map.get(gradient);
2601
+ if (isLinear) {
2602
+ // linear
2603
+ retval.setAttribute('x1', gradient.start.x.toString());
2604
+ retval.setAttribute('y1', gradient.start.y.toString());
2605
+ retval.setAttribute('x2', gradient.end.x.toString());
2606
+ retval.setAttribute('y2', gradient.end.y.toString());
2607
+ }
2608
+ else if (isRadial) {
2609
+ retval.setAttribute('cx', gradient.center.x.toString());
2610
+ retval.setAttribute('cy', gradient.center.y.toString());
2611
+ retval.setAttribute('r', gradient.radius.toString());
2612
+ }
2613
+ // stops
2614
+ let j = 0;
2615
+ for (let stop of gradient.stops) {
2616
+ while (retval.children.length <= j) {
2617
+ const stopSvgAdd = document.createElementNS(SVG_NS, 'stop');
2618
+ retval.appendChild(stopSvgAdd);
2619
+ }
2620
+ const stopSvg = retval.children.item(j);
2621
+ stopSvg.setAttribute('offset', (stop.offset * 100) + '%');
2622
+ stopSvg.setAttribute('stop-color', stop.color);
2623
+ if (!pacemCore.Utils.isNull(stop.opacity)) {
2624
+ stopSvg.setAttribute('stop-opacity', stop.opacity.toString());
2625
+ }
2626
+ j++;
2627
+ }
2628
+ while (retval.children.length > gradient.stops.length) {
2629
+ const lastChild = retval.children.item(retval.children.length - 1);
2630
+ retval.removeChild(lastChild);
2631
+ }
2632
+ return retval;
2633
+ }
2634
+ _ensureMarker(parent, marker) {
2635
+ const store = this._markers;
2636
+ if (!store.has(parent)) {
2637
+ store.set(parent, new WeakMap());
2638
+ }
2639
+ const map = store.get(parent);
2640
+ if (!map.has(marker)) {
2641
+ const markerSvg = document.createElementNS(SVG_NS, 'marker');
2642
+ map.set(marker, markerSvg);
2643
+ const markerPath = document.createElementNS(SVG_NS, 'path');
2644
+ markerSvg.appendChild(markerPath);
2645
+ markerSvg.setAttribute('id', 'mark' + pacemCore.Utils.uniqueCode());
2646
+ let defsContainer = parent;
2647
+ let defs;
2648
+ while (pacemCore.Utils.isNull(defs = defsContainer.querySelector(':scope > defs'))) {
2649
+ const parent1 = defsContainer.parentElement;
2650
+ if (parent1 instanceof SVGElement) {
2651
+ defsContainer = parent1;
2652
+ }
2653
+ else {
2654
+ break;
2655
+ }
2656
+ }
2657
+ if (pacemCore.Utils.isNull(defs)) {
2658
+ throw new Error('Must provide a <defs> element.');
2659
+ }
2660
+ defs.appendChild(markerSvg);
2661
+ }
2662
+ const markerSvg = map.get(marker), markerPath = markerSvg.firstElementChild;
2663
+ // marker attributes
2664
+ markerSvg.setAttribute('orient', 'auto-start-reverse');
2665
+ if (!pacemCore.Utils.isNullOrEmpty(marker.viewbox)) {
2666
+ markerSvg.setAttribute('viewBox', `${marker.viewbox.x} ${marker.viewbox.y} ${marker.viewbox.width} ${marker.viewbox.height}`);
2667
+ }
2668
+ else {
2669
+ markerSvg.removeAttribute('viewBox');
2670
+ }
2671
+ if (!pacemCore.Utils.isNullOrEmpty(marker.ref)) {
2672
+ markerSvg.setAttribute('refX', marker.ref.x.toString());
2673
+ markerSvg.setAttribute('refY', marker.ref.y.toString());
2674
+ }
2675
+ else {
2676
+ markerSvg.removeAttribute('refX');
2677
+ markerSvg.removeAttribute('refY');
2678
+ }
2679
+ if (marker.height > 0) {
2680
+ markerSvg.setAttribute('markerHeight', marker.height.toString());
2681
+ }
2682
+ else {
2683
+ markerSvg.removeAttribute('markerHeight');
2684
+ }
2685
+ if (marker.width > 0) {
2686
+ markerSvg.setAttribute('markerWidth', marker.width.toString());
2687
+ }
2688
+ else {
2689
+ markerSvg.removeAttribute('markerWidth');
2690
+ }
2691
+ // path attributes
2692
+ markerPath.setAttribute('d', marker.pathData);
2693
+ if (!pacemCore.Utils.isNullOrEmpty(marker.fill)) {
2694
+ markerPath.setAttribute('fill', marker.fill);
2695
+ }
2696
+ else {
2697
+ markerPath.removeAttribute('fill');
2698
+ }
2699
+ if (!pacemCore.Utils.isNullOrEmpty(marker.stroke)) {
2700
+ markerPath.setAttribute('stroke', marker.stroke);
2701
+ }
2702
+ else {
2703
+ markerPath.removeAttribute('stroke');
2704
+ }
2705
+ return markerSvg;
2706
+ }
2707
+ };
2708
+ PacemSvgAdapterElement = __decorate([
2709
+ pacemCore.CustomElement({ tagName: pacemCore.P + '-' + TAG_MIDDLE_NAME + '-svg-adapter' })
2710
+ ], PacemSvgAdapterElement);
2711
+
2712
+ var indexComponentsDrawing = /*#__PURE__*/Object.freeze({
2713
+ __proto__: null,
2714
+ AdapterUtils: AdapterUtils,
2715
+ get CornerType () { return CornerType; },
2716
+ DrawableElement: DrawableElement,
2717
+ get Pacem2DElement () { return Pacem2DElement; },
2718
+ get PacemCanvasAdapterElement () { return PacemCanvasAdapterElement; },
2719
+ get PacemCircleElement () { return PacemCircleElement; },
2720
+ get PacemEllipseElement () { return PacemEllipseElement; },
2721
+ get PacemGroupElement () { return PacemGroupElement; },
2722
+ get PacemImageElement () { return PacemImageElement; },
2723
+ get PacemLineElement () { return PacemLineElement; },
2724
+ get PacemPathElement () { return PacemPathElement; },
2725
+ get PacemPolygonElement () { return PacemPolygonElement; },
2726
+ get PacemPolylineElement () { return PacemPolylineElement; },
2727
+ get PacemRectElement () { return PacemRectElement; },
2728
+ get PacemSvgAdapterElement () { return PacemSvgAdapterElement; },
2729
+ get PacemTextElement () { return PacemTextElement; },
2730
+ PresentationElement: PresentationElement,
2731
+ ShapeElement: ShapeElement,
2732
+ UiElement: UiElement,
2733
+ getStageOptions: getStageOptions
2734
+ });
2735
+
2736
+ var indexComponents = /*#__PURE__*/Object.freeze({
2737
+ __proto__: null,
2738
+ Drawing: indexComponentsDrawing
2739
+ });
2740
+
2741
+ var Output = /*#__PURE__*/Object.freeze({
2742
+ __proto__: null,
2743
+ Components: indexComponents,
2744
+ Drawing: drawing
2745
+ });
2746
+
2747
+ pacemFoundation.DeepMerger.merge(Output);
2748
+
2749
+ })(Pacem, Pacem);
2750
+ //# sourceMappingURL=pacem-2d.js.map