@snowcone-app/canvas 0.27.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ERROR_CONTRACT.md +13 -0
- package/dist/{CanvasRenderer-yszzrDfo.js → CanvasRenderer-B_3GISlW.js} +1124 -1068
- package/dist/CanvasRenderer-B_3GISlW.js.map +1 -0
- package/dist/{CanvasStateV1-BTbCD_xC.js → CanvasStateV1-kL09wsAn.js} +3 -3
- package/dist/{CanvasStateV1-BTbCD_xC.js.map → CanvasStateV1-kL09wsAn.js.map} +1 -1
- package/dist/ContextualToolbars-C69oYLdw.js +5771 -0
- package/dist/ContextualToolbars-C69oYLdw.js.map +1 -0
- package/dist/{EditorCanvasImpl-Ui8Ceb-h.js → EditorCanvasImpl-CrI9C_xM.js} +8 -8
- package/dist/{EditorCanvasImpl-Ui8Ceb-h.js.map → EditorCanvasImpl-CrI9C_xM.js.map} +1 -1
- package/dist/{ExportManager-BTcyj4cf.js → ExportManager-J2xK86uq.js} +12 -16
- package/dist/ExportManager-J2xK86uq.js.map +1 -0
- package/dist/{FontAnalyzer-EF3gLPr8.js → FontAnalyzer-PE6nysqE.js} +658 -639
- package/dist/FontAnalyzer-PE6nysqE.js.map +1 -0
- package/dist/{ImagePanel-CIk6z41z.js → ImagePanel-CmQCxBGm.js} +6 -6
- package/dist/{ImagePanel-CIk6z41z.js.map → ImagePanel-CmQCxBGm.js.map} +1 -1
- package/dist/{SnowconeCanvas-DuWALOAt.js → SnowconeCanvas-CQiFVR0X.js} +10 -10
- package/dist/{SnowconeCanvas-DuWALOAt.js.map → SnowconeCanvas-CQiFVR0X.js.map} +1 -1
- package/dist/{UnifiedFontService-CHVYDBDW.js → UnifiedFontService-BJzoqfBF.js} +755 -713
- package/dist/UnifiedFontService-BJzoqfBF.js.map +1 -0
- package/dist/advanced.mjs +14 -14
- package/dist/components/MultiSelectionToolbar.d.ts +18 -0
- package/dist/components/ui/toolbar-button.d.ts +2 -0
- package/dist/core/GestureConstraints.d.ts +92 -0
- package/dist/core/InteractionStateMachine.d.ts +16 -2
- package/dist/core/ResizeHandler.d.ts +4 -1
- package/dist/core/ResizePipeline.d.ts +3 -0
- package/dist/{custom-icons-CcLMyybv.js → custom-icons-BWiUGqD6.js} +2 -2
- package/dist/{custom-icons-CcLMyybv.js.map → custom-icons-BWiUGqD6.js.map} +1 -1
- package/dist/{design-builder-cZY958Rw.js → design-builder-bquxIHct.js} +2 -2
- package/dist/{design-builder-cZY958Rw.js.map → design-builder-bquxIHct.js.map} +1 -1
- package/dist/{editorErrors-BhrZ_nwj.js → editorErrors-8uDRMhow.js} +2 -2
- package/dist/editorErrors-8uDRMhow.js.map +1 -0
- package/dist/{embed-CJswRZte.js → embed-L3oRIgsj.js} +10 -10
- package/dist/{embed-CJswRZte.js.map → embed-L3oRIgsj.js.map} +1 -1
- package/dist/embed.mjs +6 -6
- package/dist/errors/editorError.d.ts +7 -1
- package/dist/{guards-DIX8aXWM.js → guards-BlbhM5MX.js} +2 -2
- package/dist/{guards-DIX8aXWM.js.map → guards-BlbhM5MX.js.map} +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/useAlignDistribute.d.ts +19 -0
- package/dist/index.mjs +8 -8
- package/dist/internals.mjs +5 -5
- package/dist/{template-fields-BXl29sgh.js → template-fields-ai7vnW8g.js} +6 -6
- package/dist/{template-fields-BXl29sgh.js.map → template-fields-ai7vnW8g.js.map} +1 -1
- package/dist/testing.mjs +4 -4
- package/dist/{usePieceGuideBundle-DE21DQGZ.js → usePieceGuideBundle-CMe5br2a.js} +2 -2
- package/dist/{usePieceGuideBundle-DE21DQGZ.js.map → usePieceGuideBundle-CMe5br2a.js.map} +1 -1
- package/dist/utils/alignDistribute.d.ts +41 -0
- package/dist/{validation-DGXAQmUC.js → validation-B8kIYutI.js} +2592 -2562
- package/dist/validation-B8kIYutI.js.map +1 -0
- package/dist/workers/export-worker.bundle.string.d.ts +1 -1
- package/example/package.json +1 -1
- package/package.json +1 -1
- package/dist/CanvasRenderer-yszzrDfo.js.map +0 -1
- package/dist/ContextualToolbars-BHjYsril.js +0 -5556
- package/dist/ContextualToolbars-BHjYsril.js.map +0 -1
- package/dist/ExportManager-BTcyj4cf.js.map +0 -1
- package/dist/FontAnalyzer-EF3gLPr8.js.map +0 -1
- package/dist/UnifiedFontService-CHVYDBDW.js.map +0 -1
- package/dist/editorErrors-BhrZ_nwj.js.map +0 -1
- package/dist/validation-DGXAQmUC.js.map +0 -1
|
@@ -111,8 +111,8 @@ E.chdir = function(r) {
|
|
|
111
111
|
E.umask = function() {
|
|
112
112
|
return 0;
|
|
113
113
|
};
|
|
114
|
-
var
|
|
115
|
-
const Dt = /* @__PURE__ */ te(
|
|
114
|
+
var se = Rt.exports;
|
|
115
|
+
const Dt = /* @__PURE__ */ te(se);
|
|
116
116
|
let It = 1;
|
|
117
117
|
class nt {
|
|
118
118
|
constructor(t = {}) {
|
|
@@ -192,7 +192,7 @@ class nt {
|
|
|
192
192
|
* Returns true if point is near the border (within tolerance)
|
|
193
193
|
*/
|
|
194
194
|
hitTestBorder(t, e, o = 5) {
|
|
195
|
-
const
|
|
195
|
+
const s = t >= this.x - o && t <= this.x + this.width + o, i = e >= this.y - o && e <= this.y + this.height + o, a = Math.abs(t - this.x) <= o && i, n = Math.abs(t - (this.x + this.width)) <= o && i, h = Math.abs(e - this.y) <= o && s, l = Math.abs(e - (this.y + this.height)) <= o && s;
|
|
196
196
|
return a || n || h || l;
|
|
197
197
|
}
|
|
198
198
|
/**
|
|
@@ -210,7 +210,9 @@ class nt {
|
|
|
210
210
|
backgroundType: this.backgroundType,
|
|
211
211
|
backgroundTexture: this.backgroundTexture,
|
|
212
212
|
exportBackground: this.exportBackground,
|
|
213
|
-
|
|
213
|
+
// ClipShape is a string-or-object union — deep-copy object variants so the
|
|
214
|
+
// clone doesn't share nested path/pieces data with the original
|
|
215
|
+
clipShape: typeof this.clipShape == "object" ? structuredClone(this.clipShape) : this.clipShape,
|
|
214
216
|
previewBackgroundColor: this.previewBackgroundColor,
|
|
215
217
|
role: this.role,
|
|
216
218
|
distressTexture: this.distressTexture ? { ...this.distressTexture } : void 0,
|
|
@@ -300,11 +302,11 @@ class qe {
|
|
|
300
302
|
if (!e)
|
|
301
303
|
return [];
|
|
302
304
|
const o = e.getElementIds();
|
|
303
|
-
if (o.forEach((
|
|
304
|
-
this.elementToArtboard.delete(
|
|
305
|
+
if (o.forEach((s) => {
|
|
306
|
+
this.elementToArtboard.delete(s);
|
|
305
307
|
}), this.artboards.delete(t), this.activeArtboardId === t) {
|
|
306
|
-
const
|
|
307
|
-
this.activeArtboardId =
|
|
308
|
+
const s = Array.from(this.artboards.keys());
|
|
309
|
+
this.activeArtboardId = s.length > 0 ? s[0] : null;
|
|
308
310
|
}
|
|
309
311
|
return o;
|
|
310
312
|
}
|
|
@@ -351,10 +353,10 @@ class qe {
|
|
|
351
353
|
const o = this.artboards.get(e);
|
|
352
354
|
if (!o)
|
|
353
355
|
return !1;
|
|
354
|
-
const
|
|
355
|
-
if (
|
|
356
|
-
const
|
|
357
|
-
|
|
356
|
+
const s = this.elementToArtboard.get(t);
|
|
357
|
+
if (s) {
|
|
358
|
+
const i = this.artboards.get(s);
|
|
359
|
+
i == null || i.removeElementId(t);
|
|
358
360
|
}
|
|
359
361
|
return o.addElementId(t), this.elementToArtboard.set(t, e), !0;
|
|
360
362
|
}
|
|
@@ -394,19 +396,19 @@ class qe {
|
|
|
394
396
|
*/
|
|
395
397
|
findArtboardAtPoint(t, e) {
|
|
396
398
|
const o = Array.from(this.artboards.values()).reverse();
|
|
397
|
-
for (const
|
|
398
|
-
if (
|
|
399
|
-
return
|
|
399
|
+
for (const s of o)
|
|
400
|
+
if (s.containsPoint(t, e))
|
|
401
|
+
return s;
|
|
400
402
|
return null;
|
|
401
403
|
}
|
|
402
404
|
/**
|
|
403
405
|
* Find artboard border at point (for resize handles)
|
|
404
406
|
*/
|
|
405
407
|
findArtboardBorderAtPoint(t, e, o = 5) {
|
|
406
|
-
const
|
|
407
|
-
for (const
|
|
408
|
-
if (
|
|
409
|
-
return
|
|
408
|
+
const s = Array.from(this.artboards.values()).reverse();
|
|
409
|
+
for (const i of s)
|
|
410
|
+
if (i.hitTestBorder(t, e, o))
|
|
411
|
+
return i;
|
|
410
412
|
return null;
|
|
411
413
|
}
|
|
412
414
|
/**
|
|
@@ -447,8 +449,8 @@ class qe {
|
|
|
447
449
|
reorderArtboards(t, e) {
|
|
448
450
|
const o = Array.from(this.artboards.entries());
|
|
449
451
|
if (t < 0 || t >= o.length || e < 0 || e >= o.length || t === e) return;
|
|
450
|
-
const [
|
|
451
|
-
o.splice(e, 0,
|
|
452
|
+
const [s] = o.splice(t, 1);
|
|
453
|
+
o.splice(e, 0, s), this.artboards = new Map(o);
|
|
452
454
|
}
|
|
453
455
|
/**
|
|
454
456
|
* Clear all artboards
|
|
@@ -471,8 +473,8 @@ class qe {
|
|
|
471
473
|
fromJSON(t) {
|
|
472
474
|
this.clear(), t.artboards.forEach((e) => {
|
|
473
475
|
const o = nt.fromJSON(e);
|
|
474
|
-
this.artboards.set(o.id, o), o.getElementIds().forEach((
|
|
475
|
-
this.elementToArtboard.set(
|
|
476
|
+
this.artboards.set(o.id, o), o.getElementIds().forEach((s) => {
|
|
477
|
+
this.elementToArtboard.set(s, o.id);
|
|
476
478
|
});
|
|
477
479
|
}), this.activeArtboardId = t.activeArtboardId;
|
|
478
480
|
}
|
|
@@ -482,11 +484,11 @@ class qe {
|
|
|
482
484
|
*/
|
|
483
485
|
validateMappings(t) {
|
|
484
486
|
const e = new Set(t.map((o) => o.id));
|
|
485
|
-
for (const [o,
|
|
487
|
+
for (const [o, s] of this.elementToArtboard.entries())
|
|
486
488
|
e.has(o) || this.removeElementFromArtboard(o);
|
|
487
489
|
for (const o of this.artboards.values()) {
|
|
488
|
-
const
|
|
489
|
-
o.clearElementIds(),
|
|
490
|
+
const s = o.getElementIds().filter((i) => e.has(i));
|
|
491
|
+
o.clearElementIds(), s.forEach((i) => o.addElementId(i));
|
|
490
492
|
}
|
|
491
493
|
}
|
|
492
494
|
}
|
|
@@ -519,7 +521,7 @@ const D = {
|
|
|
519
521
|
return t > 180 && (t -= 360), t;
|
|
520
522
|
}
|
|
521
523
|
};
|
|
522
|
-
let
|
|
524
|
+
let ie = 1;
|
|
523
525
|
class Q {
|
|
524
526
|
/** Whether this element clips content below it (derived from blendMode === 'clip') */
|
|
525
527
|
get isClipping() {
|
|
@@ -529,7 +531,7 @@ class Q {
|
|
|
529
531
|
t ? (this.blendMode = "clip", this.knockoutParts || (this.knockoutParts = { fill: !0, scope: "group" })) : this.blendMode === "clip" && (this.blendMode = "normal");
|
|
530
532
|
}
|
|
531
533
|
constructor(t = {}) {
|
|
532
|
-
this.id = t.id || `element-${
|
|
534
|
+
this.id = t.id || `element-${ie++}`, this.x = t.x !== void 0 ? t.x : 100, this.y = t.y !== void 0 ? t.y : 100, this.rotation = t.rotation !== void 0 ? t.rotation : 0, this.opacity = t.opacity !== void 0 ? t.opacity : 1, this.transformType = t.transformType || "custom", this.transformData = t.transformData || {}, this.blendMode = t.blendMode, this.knockoutParts = t.knockoutParts, this.stroke = t.stroke, this.masks = t.masks, this.distressEffect = t.distressEffect, t.isClipping && !t.blendMode && (this.blendMode = "clip", this.knockoutParts || (this.knockoutParts = { fill: !0, scope: "group" })), this.name = t.name, this.visible = t.visible !== void 0 ? t.visible : !0, this.locked = t.locked !== void 0 ? t.locked : !1;
|
|
533
535
|
}
|
|
534
536
|
/**
|
|
535
537
|
* Get visual bounding box (tight fit around actual rendered content)
|
|
@@ -552,7 +554,7 @@ class Q {
|
|
|
552
554
|
* Uses visual bounding box for better user experience
|
|
553
555
|
*/
|
|
554
556
|
hitTest(t, e) {
|
|
555
|
-
const o = this.getVisualBoundingBox(),
|
|
557
|
+
const o = this.getVisualBoundingBox(), s = this.getRotationAnchor(), i = D.toRadiansInverse(this.rotation), a = Math.cos(i), n = Math.sin(i), h = t - s.x, l = e - s.y, c = h * a - l * n, g = h * n + l * a, d = s.x + c, f = s.y + g;
|
|
556
558
|
return d >= o.x && d <= o.x + o.width && f >= o.y && f <= o.y + o.height;
|
|
557
559
|
}
|
|
558
560
|
/**
|
|
@@ -578,8 +580,16 @@ class Q {
|
|
|
578
580
|
// Effects properties (only include if defined)
|
|
579
581
|
...this.blendMode && { blendMode: this.blendMode },
|
|
580
582
|
...this.knockoutParts && { knockoutParts: { ...this.knockoutParts } },
|
|
581
|
-
...this.stroke && {
|
|
582
|
-
|
|
583
|
+
...this.stroke && {
|
|
584
|
+
stroke: {
|
|
585
|
+
...this.stroke,
|
|
586
|
+
...this.stroke.dashArray && { dashArray: [...this.stroke.dashArray] }
|
|
587
|
+
}
|
|
588
|
+
},
|
|
589
|
+
// maskElement is a nested config object — structuredClone so clones don't share it
|
|
590
|
+
...this.masks && {
|
|
591
|
+
masks: this.masks.map((t) => ({ ...t, maskElement: structuredClone(t.maskElement) }))
|
|
592
|
+
},
|
|
583
593
|
...this.distressEffect && { distressEffect: { ...this.distressEffect } },
|
|
584
594
|
// Layer properties (only include if defined)
|
|
585
595
|
...this.name && { name: this.name },
|
|
@@ -655,10 +665,10 @@ class R {
|
|
|
655
665
|
* @returns Point in local coordinates
|
|
656
666
|
*/
|
|
657
667
|
worldToLocal(t, e) {
|
|
658
|
-
const o = this.element.rotation * Math.PI / 180,
|
|
668
|
+
const o = this.element.rotation * Math.PI / 180, s = Math.cos(o), i = Math.sin(o), a = t - this.element.x, n = e - this.element.y;
|
|
659
669
|
return {
|
|
660
|
-
x: a *
|
|
661
|
-
y: a *
|
|
670
|
+
x: a * s - n * i,
|
|
671
|
+
y: a * i + n * s
|
|
662
672
|
};
|
|
663
673
|
}
|
|
664
674
|
/**
|
|
@@ -671,7 +681,7 @@ class R {
|
|
|
671
681
|
* @returns Point in world coordinates
|
|
672
682
|
*/
|
|
673
683
|
localToWorld(t, e) {
|
|
674
|
-
const o = -this.element.rotation * Math.PI / 180,
|
|
684
|
+
const o = -this.element.rotation * Math.PI / 180, s = Math.cos(o), i = Math.sin(o), a = t * s - e * i, n = t * i + e * s;
|
|
675
685
|
return {
|
|
676
686
|
x: this.element.x + a,
|
|
677
687
|
y: this.element.y + n
|
|
@@ -687,10 +697,10 @@ class R {
|
|
|
687
697
|
* @returns Delta in local space
|
|
688
698
|
*/
|
|
689
699
|
worldDeltaToLocal(t, e) {
|
|
690
|
-
const o = this.element.rotation * Math.PI / 180,
|
|
700
|
+
const o = this.element.rotation * Math.PI / 180, s = Math.cos(o), i = Math.sin(o);
|
|
691
701
|
return {
|
|
692
|
-
dx: t *
|
|
693
|
-
dy: t *
|
|
702
|
+
dx: t * s - e * i,
|
|
703
|
+
dy: t * i + e * s
|
|
694
704
|
};
|
|
695
705
|
}
|
|
696
706
|
/**
|
|
@@ -702,10 +712,10 @@ class R {
|
|
|
702
712
|
* @returns Delta in world space
|
|
703
713
|
*/
|
|
704
714
|
localDeltaToWorld(t, e) {
|
|
705
|
-
const o = -this.element.rotation * Math.PI / 180,
|
|
715
|
+
const o = -this.element.rotation * Math.PI / 180, s = Math.cos(o), i = Math.sin(o);
|
|
706
716
|
return {
|
|
707
|
-
dx: t *
|
|
708
|
-
dy: t *
|
|
717
|
+
dx: t * s - e * i,
|
|
718
|
+
dy: t * i + e * s
|
|
709
719
|
};
|
|
710
720
|
}
|
|
711
721
|
/**
|
|
@@ -719,11 +729,11 @@ class R {
|
|
|
719
729
|
* @param angleDegrees - Rotation angle in degrees (positive = clockwise in UI)
|
|
720
730
|
* @returns Rotated point in world space
|
|
721
731
|
*/
|
|
722
|
-
static rotatePointAroundAnchor(t, e, o,
|
|
723
|
-
const a = -
|
|
732
|
+
static rotatePointAroundAnchor(t, e, o, s, i) {
|
|
733
|
+
const a = -i * Math.PI / 180, n = Math.cos(a), h = Math.sin(a), l = t - o, c = e - s, g = l * n - c * h, d = l * h + c * n;
|
|
724
734
|
return {
|
|
725
735
|
x: o + g,
|
|
726
|
-
y:
|
|
736
|
+
y: s + d
|
|
727
737
|
};
|
|
728
738
|
}
|
|
729
739
|
/**
|
|
@@ -2295,8 +2305,8 @@ function Ke(r = 0.1, t) {
|
|
|
2295
2305
|
if (e.startsWith("oklch("))
|
|
2296
2306
|
return `${e.slice(0, -1)} / ${r})`;
|
|
2297
2307
|
if (e.startsWith("#")) {
|
|
2298
|
-
const o = e.replace("#", ""),
|
|
2299
|
-
return `rgba(${
|
|
2308
|
+
const o = e.replace("#", ""), s = parseInt(o.substring(0, 2), 16), i = parseInt(o.substring(2, 4), 16), a = parseInt(o.substring(4, 6), 16);
|
|
2309
|
+
return `rgba(${s}, ${i}, ${a}, ${r})`;
|
|
2300
2310
|
}
|
|
2301
2311
|
return e;
|
|
2302
2312
|
}
|
|
@@ -2328,13 +2338,13 @@ function oo(r) {
|
|
|
2328
2338
|
const t = he(r);
|
|
2329
2339
|
return t.startsWith("oklch(") ? `${t.slice(0, -1)} / 0.2)` : "rgba(0,0,0,0.2)";
|
|
2330
2340
|
}
|
|
2331
|
-
function
|
|
2341
|
+
function so(r) {
|
|
2332
2342
|
if (typeof window > "u" || typeof document > "u")
|
|
2333
2343
|
return "oklch(0% 0 0 / 0.2)";
|
|
2334
2344
|
const t = document.documentElement;
|
|
2335
2345
|
return getComputedStyle(t).getPropertyValue("--divider").trim() || "oklch(0% 0 0 / 0.2)";
|
|
2336
2346
|
}
|
|
2337
|
-
function
|
|
2347
|
+
function io(r) {
|
|
2338
2348
|
if (typeof window > "u" || typeof document > "u")
|
|
2339
2349
|
return "oklch(0% 0 0 / 0.5)";
|
|
2340
2350
|
const t = document.documentElement, e = getComputedStyle(t).getPropertyValue("--foreground").trim();
|
|
@@ -2503,16 +2513,16 @@ class J {
|
|
|
2503
2513
|
return e.refCount++, e.image;
|
|
2504
2514
|
const o = new Image();
|
|
2505
2515
|
o.crossOrigin = "anonymous";
|
|
2506
|
-
const
|
|
2516
|
+
const s = {
|
|
2507
2517
|
image: o,
|
|
2508
2518
|
refCount: 1,
|
|
2509
2519
|
loaded: !1
|
|
2510
2520
|
};
|
|
2511
2521
|
return o.onload = () => {
|
|
2512
|
-
|
|
2522
|
+
s.loaded = !0;
|
|
2513
2523
|
}, o.onerror = () => {
|
|
2514
|
-
|
|
2515
|
-
}, this.cache.set(t,
|
|
2524
|
+
s.loaded = !0;
|
|
2525
|
+
}, this.cache.set(t, s), (!t.includes(":") || /^https?:\/\/|^data:|^blob:/.test(t)) && (o.src = t), o;
|
|
2516
2526
|
}
|
|
2517
2527
|
/**
|
|
2518
2528
|
* Release a reference to a cached image.
|
|
@@ -2568,13 +2578,13 @@ function C(r) {
|
|
|
2568
2578
|
class pt extends Q {
|
|
2569
2579
|
// Track URL acquired from ImageCache for release on destroy
|
|
2570
2580
|
constructor(t = {}) {
|
|
2571
|
-
var e, o,
|
|
2581
|
+
var e, o, s, i, a, n, h, l, c, g;
|
|
2572
2582
|
super(t), this.svgBlobUrl = null, this.loadTimeoutId = null, this.retryAttempt = 0, this.cachedImageUrl = null, this.transformType = "image", this.transformData = {
|
|
2573
2583
|
type: "image",
|
|
2574
2584
|
width: ((e = t.transformData) == null ? void 0 : e.width) || 200,
|
|
2575
2585
|
height: ((o = t.transformData) == null ? void 0 : o.height) || 200,
|
|
2576
|
-
cropX: ((
|
|
2577
|
-
cropY: ((
|
|
2586
|
+
cropX: ((s = t.transformData) == null ? void 0 : s.cropX) ?? 0,
|
|
2587
|
+
cropY: ((i = t.transformData) == null ? void 0 : i.cropY) ?? 0,
|
|
2578
2588
|
cropWidth: ((a = t.transformData) == null ? void 0 : a.cropWidth) ?? 1,
|
|
2579
2589
|
cropHeight: ((n = t.transformData) == null ? void 0 : n.cropHeight) ?? 1,
|
|
2580
2590
|
flipHorizontal: ((h = t.transformData) == null ? void 0 : h.flipHorizontal) ?? !1,
|
|
@@ -2609,28 +2619,28 @@ class pt extends Q {
|
|
|
2609
2619
|
this.clearLoadTimeout(), this.releaseImageCache();
|
|
2610
2620
|
const o = J.getInstance().acquire(t);
|
|
2611
2621
|
this.cachedImageUrl = t;
|
|
2612
|
-
let
|
|
2613
|
-
const
|
|
2614
|
-
|
|
2622
|
+
let s = !1;
|
|
2623
|
+
const i = () => {
|
|
2624
|
+
s = !0, this.clearLoadTimeout();
|
|
2615
2625
|
};
|
|
2616
2626
|
if (o.complete && o.naturalWidth > 0) {
|
|
2617
|
-
|
|
2627
|
+
i(), this.imageElement = o, this.imageLoaded = !0, this.imageLoadState = "loaded", this.imageLoadError = null, this.imageAspectRatio = o.naturalWidth / o.naturalHeight, this.preserveDimensions || (this.transformData.height = this.transformData.width / this.imageAspectRatio), this.onLoadCallback && this.onLoadCallback(this.clone()), et(this.id);
|
|
2618
2628
|
return;
|
|
2619
2629
|
}
|
|
2620
2630
|
const a = o.onload, n = o.onerror;
|
|
2621
2631
|
o.onload = (l) => {
|
|
2622
|
-
|
|
2632
|
+
s || (i(), this.imageElement = o, this.imageLoaded = !0, this.imageLoadState = "loaded", this.imageLoadError = null, this.imageAspectRatio = o.naturalWidth / o.naturalHeight, this.preserveDimensions || (this.transformData.height = this.transformData.width / this.imageAspectRatio), this.onLoadCallback && this.onLoadCallback(this.clone()), et(this.id), a && a !== o.onload && a(l));
|
|
2623
2633
|
}, o.onerror = (l) => {
|
|
2624
|
-
if (
|
|
2625
|
-
|
|
2634
|
+
if (s) return;
|
|
2635
|
+
i();
|
|
2626
2636
|
const c = new Error(`Failed to load image: ${t}`);
|
|
2627
2637
|
this.handleLoadFailure(t, c), n && n !== o.onerror && n(l);
|
|
2628
2638
|
}, this.loadTimeoutId = setTimeout(() => {
|
|
2629
|
-
if (
|
|
2630
|
-
|
|
2639
|
+
if (s) return;
|
|
2640
|
+
i(), o.src = "";
|
|
2631
2641
|
const l = new Error(`Image load timed out after ${kt}ms: ${t}`);
|
|
2632
2642
|
this.handleLoadFailure(t, l);
|
|
2633
|
-
}, kt), (!o.src || o.src !== t) && (o.src = t), !
|
|
2643
|
+
}, kt), (!o.src || o.src !== t) && (o.src = t), !s && o.complete && o.naturalWidth > 0 && ((h = o.onload) == null || h.call(o, new Event("load")));
|
|
2634
2644
|
}
|
|
2635
2645
|
/**
|
|
2636
2646
|
* Handle a load failure - either retry with backoff or set error state.
|
|
@@ -2679,10 +2689,10 @@ class pt extends Q {
|
|
|
2679
2689
|
this.revokeSvgBlobUrl();
|
|
2680
2690
|
const e = new Image();
|
|
2681
2691
|
e.crossOrigin = "anonymous", e.onload = () => {
|
|
2682
|
-
const
|
|
2683
|
-
|
|
2684
|
-
const
|
|
2685
|
-
|
|
2692
|
+
const s = document.createElement("canvas");
|
|
2693
|
+
s.width = e.width * 4, s.height = e.height * 4;
|
|
2694
|
+
const i = s.getContext("2d");
|
|
2695
|
+
i.scale(4, 4), i.drawImage(e, 0, 0), s.toBlob((a) => {
|
|
2686
2696
|
if (!a) {
|
|
2687
2697
|
ot.error("Failed to convert SVG to blob"), this.imageLoaded = !1;
|
|
2688
2698
|
return;
|
|
@@ -2703,10 +2713,10 @@ class pt extends Q {
|
|
|
2703
2713
|
getBoundingBox() {
|
|
2704
2714
|
if (this.isCropping) {
|
|
2705
2715
|
const t = this.transformData.width * this.transformData.cropWidth, e = this.transformData.height * this.transformData.cropHeight;
|
|
2706
|
-
let o = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + t / 2),
|
|
2707
|
-
const
|
|
2708
|
-
o *=
|
|
2709
|
-
const n = Math.cos(D.toRadians(this.rotation)), h = Math.sin(D.toRadians(this.rotation)), l = o * n -
|
|
2716
|
+
let o = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + t / 2), s = this.transformData.height / 2 - (this.transformData.cropY * this.transformData.height + e / 2);
|
|
2717
|
+
const i = this.transformData.flipHorizontal ? -1 : 1, a = this.transformData.flipVertical ? -1 : 1;
|
|
2718
|
+
o *= i, s *= a;
|
|
2719
|
+
const n = Math.cos(D.toRadians(this.rotation)), h = Math.sin(D.toRadians(this.rotation)), l = o * n - s * h, c = o * h + s * n, g = this.x + l, d = this.y + c;
|
|
2710
2720
|
return {
|
|
2711
2721
|
x: g - this.transformData.width / 2,
|
|
2712
2722
|
y: d - this.transformData.height / 2,
|
|
@@ -2744,10 +2754,10 @@ class pt extends Q {
|
|
|
2744
2754
|
getRotationAnchor() {
|
|
2745
2755
|
if (this.isCropping) {
|
|
2746
2756
|
const t = this.transformData.width * this.transformData.cropWidth, e = this.transformData.height * this.transformData.cropHeight;
|
|
2747
|
-
let o = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + t / 2),
|
|
2748
|
-
const
|
|
2749
|
-
o *=
|
|
2750
|
-
const n = Math.cos(D.toRadians(this.rotation)), h = Math.sin(D.toRadians(this.rotation)), l = o * n -
|
|
2757
|
+
let o = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + t / 2), s = this.transformData.height / 2 - (this.transformData.cropY * this.transformData.height + e / 2);
|
|
2758
|
+
const i = this.transformData.flipHorizontal ? -1 : 1, a = this.transformData.flipVertical ? -1 : 1;
|
|
2759
|
+
o *= i, s *= a;
|
|
2760
|
+
const n = Math.cos(D.toRadians(this.rotation)), h = Math.sin(D.toRadians(this.rotation)), l = o * n - s * h, c = o * h + s * n;
|
|
2751
2761
|
return {
|
|
2752
2762
|
x: this.x + l,
|
|
2753
2763
|
y: this.y + c
|
|
@@ -2764,10 +2774,10 @@ class pt extends Q {
|
|
|
2764
2774
|
hitTest(t, e) {
|
|
2765
2775
|
const o = this.worldToLocal(t, e);
|
|
2766
2776
|
if (this.isCropping) {
|
|
2767
|
-
const
|
|
2777
|
+
const s = this.transformData.width * this.transformData.cropWidth, i = this.transformData.height * this.transformData.cropHeight, a = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + s / 2), n = this.transformData.height / 2 - (this.transformData.cropY * this.transformData.height + i / 2), h = this.transformData.width / 2, l = this.transformData.height / 2;
|
|
2768
2778
|
return o.x >= a - h && o.x <= a + h && o.y >= n - l && o.y <= n + l;
|
|
2769
2779
|
} else {
|
|
2770
|
-
const
|
|
2780
|
+
const s = this.transformData.width * this.transformData.cropWidth, i = this.transformData.height * this.transformData.cropHeight, a = s / 2, n = i / 2;
|
|
2771
2781
|
return o.x >= -a && o.x <= a && o.y >= -n && o.y <= n;
|
|
2772
2782
|
}
|
|
2773
2783
|
}
|
|
@@ -2780,8 +2790,8 @@ class pt extends Q {
|
|
|
2780
2790
|
return;
|
|
2781
2791
|
}
|
|
2782
2792
|
t.save(), this.opacity !== void 0 && this.opacity !== 1 && (t.globalAlpha = this.opacity), t.translate(this.x, this.y), t.rotate(D.toRadians(this.rotation));
|
|
2783
|
-
const
|
|
2784
|
-
if (t.scale(
|
|
2793
|
+
const s = this.transformData.flipHorizontal ? -1 : 1, i = this.transformData.flipVertical ? -1 : 1;
|
|
2794
|
+
if (t.scale(s, i), this.isCropping) {
|
|
2785
2795
|
const a = this.transformData.width * this.transformData.cropWidth, n = this.transformData.height * this.transformData.cropHeight, h = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + a / 2), l = this.transformData.height / 2 - (this.transformData.cropY * this.transformData.height + n / 2), c = h - this.transformData.width / 2, g = l - this.transformData.height / 2, d = this.transformData.borderRadius || 0;
|
|
2786
2796
|
if (d > 0) {
|
|
2787
2797
|
t.save();
|
|
@@ -2842,48 +2852,48 @@ class pt extends Q {
|
|
|
2842
2852
|
*/
|
|
2843
2853
|
renderPlaceholder(t) {
|
|
2844
2854
|
t.save(), t.translate(this.x, this.y), t.rotate(D.toRadians(this.rotation));
|
|
2845
|
-
const e = this.transformData.width * this.transformData.cropWidth, o = this.transformData.height * this.transformData.cropHeight,
|
|
2855
|
+
const e = this.transformData.width * this.transformData.cropWidth, o = this.transformData.height * this.transformData.cropHeight, s = -e / 2, i = -o / 2;
|
|
2846
2856
|
let a, n, h;
|
|
2847
|
-
this.imageLoadState === "error" ? (a = "#f0e0e0", n = "#993333", h = "Image failed to load") : this.imageLoadState === "retrying" ? (a = "#e0e0e0", n = "#666", h = "Retrying...") : this.imageLoadState === "loading" ? (a = "#e0e0e0", n = "#666", h = "Loading...") : (a = "#e0e0e0", n = "#666", h = this.imageUrl ? "Loading..." : "No image"), t.fillStyle = a, t.fillRect(
|
|
2857
|
+
this.imageLoadState === "error" ? (a = "#f0e0e0", n = "#993333", h = "Image failed to load") : this.imageLoadState === "retrying" ? (a = "#e0e0e0", n = "#666", h = "Retrying...") : this.imageLoadState === "loading" ? (a = "#e0e0e0", n = "#666", h = "Loading...") : (a = "#e0e0e0", n = "#666", h = this.imageUrl ? "Loading..." : "No image"), t.fillStyle = a, t.fillRect(s, i, e, o), t.fillStyle = n, t.font = "14px system-ui, -apple-system, sans-serif", t.textAlign = "center", t.textBaseline = "middle", t.fillText(h, 0, 0), t.restore();
|
|
2848
2858
|
}
|
|
2849
2859
|
/**
|
|
2850
2860
|
* Handle resize - maintain aspect ratio
|
|
2851
2861
|
* @returns {boolean} true if resize was applied
|
|
2852
2862
|
*/
|
|
2853
|
-
resize(t, e, o,
|
|
2854
|
-
let
|
|
2855
|
-
this.isCropping ? (
|
|
2856
|
-
const n = (
|
|
2863
|
+
resize(t, e, o, s) {
|
|
2864
|
+
let i, a;
|
|
2865
|
+
this.isCropping ? (i = e / C(s).width, a = o / C(s).height) : (i = e / (s.width ?? 1), a = o / (s.height ?? 1));
|
|
2866
|
+
const n = (i + a) / 2;
|
|
2857
2867
|
let h = t;
|
|
2858
|
-
this.isCropping && (h = this.remapAnchorForFlips(t,
|
|
2868
|
+
this.isCropping && (h = this.remapAnchorForFlips(t, s));
|
|
2859
2869
|
let l = n;
|
|
2860
2870
|
if (this.isCropping) {
|
|
2861
|
-
const I = this.transformData.width / C(
|
|
2871
|
+
const I = this.transformData.width / C(s).width;
|
|
2862
2872
|
n < I && (l = this.calculateMinScaleForCropBounds(
|
|
2863
2873
|
h,
|
|
2864
|
-
|
|
2874
|
+
s,
|
|
2865
2875
|
n,
|
|
2866
2876
|
I
|
|
2867
2877
|
));
|
|
2868
2878
|
}
|
|
2869
|
-
this.transformData.width = C(
|
|
2879
|
+
this.transformData.width = C(s).width * l, this.transformData.height = this.transformData.width / this.imageAspectRatio, this.rotation = s.rotation;
|
|
2870
2880
|
let c, g;
|
|
2871
2881
|
if (this.isCropping) {
|
|
2872
|
-
const I = (C(
|
|
2873
|
-
c =
|
|
2882
|
+
const I = (C(s).cropX + C(s).cropWidth / 2) * C(s).width - C(s).width / 2, O = (C(s).cropY + C(s).cropHeight / 2) * C(s).height - C(s).height / 2, B = I, L = O, H = R.fromSnapshot(s).localDeltaToWorld(B, L), G = H.dx, $ = H.dy;
|
|
2883
|
+
c = s.x - G, g = s.y - $;
|
|
2874
2884
|
} else {
|
|
2875
|
-
const I = (C(
|
|
2876
|
-
c =
|
|
2885
|
+
const I = (C(s).cropX + C(s).cropWidth / 2) * C(s).width - C(s).width / 2, O = (C(s).cropY + C(s).cropHeight / 2) * C(s).height - C(s).height / 2, B = I, L = O, H = R.fromSnapshot(s).localDeltaToWorld(B, L), G = H.dx, $ = H.dy;
|
|
2886
|
+
c = s.x - G, g = s.y - $;
|
|
2877
2887
|
}
|
|
2878
2888
|
let d, f, u = 0, m = 0;
|
|
2879
|
-
h === "top-left" ? (u = C(
|
|
2880
|
-
const y = R.fromSnapshot(
|
|
2889
|
+
h === "top-left" ? (u = C(s).width / 2, m = C(s).height / 2) : h === "top-right" ? (u = -C(s).width / 2, m = C(s).height / 2) : h === "bottom-left" ? (u = C(s).width / 2, m = -C(s).height / 2) : h === "bottom-right" ? (u = -C(s).width / 2, m = -C(s).height / 2) : h === "middle-left" ? (u = C(s).width / 2, m = 0) : h === "middle-right" ? (u = -C(s).width / 2, m = 0) : h === "middle-top" ? (u = 0, m = C(s).height / 2) : h === "middle-bottom" && (u = 0, m = -C(s).height / 2);
|
|
2890
|
+
const y = R.fromSnapshot(s).localDeltaToWorld(u, m), x = y.dx, b = y.dy;
|
|
2881
2891
|
d = c + x, f = g + b;
|
|
2882
2892
|
let S = 0, v = 0;
|
|
2883
2893
|
h === "top-left" ? (S = this.transformData.width / 2, v = this.transformData.height / 2) : h === "top-right" ? (S = -this.transformData.width / 2, v = this.transformData.height / 2) : h === "bottom-left" ? (S = this.transformData.width / 2, v = -this.transformData.height / 2) : h === "bottom-right" ? (S = -this.transformData.width / 2, v = -this.transformData.height / 2) : h === "middle-left" ? (S = this.transformData.width / 2, v = 0) : h === "middle-right" ? (S = -this.transformData.width / 2, v = 0) : h === "middle-top" ? (S = 0, v = this.transformData.height / 2) : h === "middle-bottom" && (S = 0, v = -this.transformData.height / 2);
|
|
2884
2894
|
const T = new R(this).localDeltaToWorld(S, v), F = T.dx, A = T.dy, M = d - F, k = f - A;
|
|
2885
2895
|
if (this.isCropping) {
|
|
2886
|
-
const I =
|
|
2896
|
+
const I = s.x, O = s.y, B = C(s).cropWidth * C(s).width, L = C(s).cropHeight * C(s).height;
|
|
2887
2897
|
this.x = I, this.y = O;
|
|
2888
2898
|
const _ = B / this.transformData.width, H = L / this.transformData.height, G = I - M, $ = O - k, At = new R(this).worldDeltaToLocal(G, $), Jt = At.dx, qt = At.dy, jt = this.transformData.width / 2 + Jt, Zt = this.transformData.height / 2 + qt, Kt = jt / this.transformData.width - _ / 2, Qt = Zt / this.transformData.height - H / 2;
|
|
2889
2899
|
this.transformData.cropX = Kt, this.transformData.cropY = Qt, this.transformData.cropWidth = _, this.transformData.cropHeight = H;
|
|
@@ -2945,9 +2955,9 @@ class pt extends Q {
|
|
|
2945
2955
|
// bottom-left
|
|
2946
2956
|
{ x: t.x + t.width, y: t.y + t.height }
|
|
2947
2957
|
// bottom-right
|
|
2948
|
-
].map((
|
|
2949
|
-
x: this.x +
|
|
2950
|
-
y: this.y +
|
|
2958
|
+
].map((i) => ({
|
|
2959
|
+
x: this.x + i.x * e - i.y * o,
|
|
2960
|
+
y: this.y + i.x * o + i.y * e
|
|
2951
2961
|
}));
|
|
2952
2962
|
}
|
|
2953
2963
|
/**
|
|
@@ -2955,8 +2965,8 @@ class pt extends Q {
|
|
|
2955
2965
|
* Local coordinates are relative to this.x, this.y (the center of the visible area)
|
|
2956
2966
|
*/
|
|
2957
2967
|
worldToLocal(t, e) {
|
|
2958
|
-
const o = t - this.x,
|
|
2959
|
-
let n = o *
|
|
2968
|
+
const o = t - this.x, s = e - this.y, i = Math.cos(D.toRadiansInverse(this.rotation)), a = Math.sin(D.toRadiansInverse(this.rotation));
|
|
2969
|
+
let n = o * i - s * a, h = o * a + s * i;
|
|
2960
2970
|
const l = this.transformData.flipHorizontal ? -1 : 1, c = this.transformData.flipVertical ? -1 : 1;
|
|
2961
2971
|
return n *= l, h *= c, {
|
|
2962
2972
|
x: n,
|
|
@@ -2969,9 +2979,9 @@ class pt extends Q {
|
|
|
2969
2979
|
* Canvas transformations are applied in reverse: scale -> rotate -> translate
|
|
2970
2980
|
*/
|
|
2971
2981
|
localToWorld(t, e) {
|
|
2972
|
-
const o = this.transformData.flipHorizontal ? -1 : 1,
|
|
2973
|
-
let
|
|
2974
|
-
const n = Math.cos(D.toRadians(this.rotation)), h = Math.sin(D.toRadians(this.rotation)), l =
|
|
2982
|
+
const o = this.transformData.flipHorizontal ? -1 : 1, s = this.transformData.flipVertical ? -1 : 1;
|
|
2983
|
+
let i = t * o, a = e * s;
|
|
2984
|
+
const n = Math.cos(D.toRadians(this.rotation)), h = Math.sin(D.toRadians(this.rotation)), l = i * n - a * h, c = i * h + a * n;
|
|
2975
2985
|
return {
|
|
2976
2986
|
x: this.x + l,
|
|
2977
2987
|
y: this.y + c
|
|
@@ -2986,29 +2996,29 @@ class pt extends Q {
|
|
|
2986
2996
|
*/
|
|
2987
2997
|
hitTestCropHandle(t, e, o = 1) {
|
|
2988
2998
|
if (!this.isCropping) return null;
|
|
2989
|
-
const
|
|
2990
|
-
if (!
|
|
2991
|
-
const
|
|
2992
|
-
{ x:
|
|
2993
|
-
{ x:
|
|
2994
|
-
{ x:
|
|
2995
|
-
{ x:
|
|
2999
|
+
const s = this.getCropBoxBounds();
|
|
3000
|
+
if (!s) return null;
|
|
3001
|
+
const i = this.worldToLocal(t, e), a = 1 / o, n = ce * a, h = de * a, l = ge * a, c = [
|
|
3002
|
+
{ x: s.x, y: s.y, anchor: "top-left" },
|
|
3003
|
+
{ x: s.x + s.width, y: s.y, anchor: "top-right" },
|
|
3004
|
+
{ x: s.x, y: s.y + s.height, anchor: "bottom-left" },
|
|
3005
|
+
{ x: s.x + s.width, y: s.y + s.height, anchor: "bottom-right" }
|
|
2996
3006
|
];
|
|
2997
3007
|
for (const d of c) {
|
|
2998
|
-
const f =
|
|
3008
|
+
const f = i.x - d.x, u = i.y - d.y;
|
|
2999
3009
|
if (Math.sqrt(f * f + u * u) <= n) {
|
|
3000
3010
|
const p = this.localToWorld(d.x, d.y);
|
|
3001
3011
|
return { type: "corner", anchor: d.anchor, worldX: p.x, worldY: p.y };
|
|
3002
3012
|
}
|
|
3003
3013
|
}
|
|
3004
3014
|
const g = [
|
|
3005
|
-
{ x:
|
|
3006
|
-
{ x:
|
|
3007
|
-
{ x:
|
|
3008
|
-
{ x:
|
|
3015
|
+
{ x: s.x + s.width / 2, y: s.y, anchor: "top", orientation: "horizontal" },
|
|
3016
|
+
{ x: s.x + s.width / 2, y: s.y + s.height, anchor: "bottom", orientation: "horizontal" },
|
|
3017
|
+
{ x: s.x, y: s.y + s.height / 2, anchor: "left", orientation: "vertical" },
|
|
3018
|
+
{ x: s.x + s.width, y: s.y + s.height / 2, anchor: "right", orientation: "vertical" }
|
|
3009
3019
|
];
|
|
3010
3020
|
for (const d of g) {
|
|
3011
|
-
const f =
|
|
3021
|
+
const f = i.x - d.x, u = i.y - d.y;
|
|
3012
3022
|
let m, p;
|
|
3013
3023
|
if (d.orientation === "horizontal" ? (m = h / 2, p = l / 2) : (m = l / 2, p = h / 2), Math.abs(f) <= m && Math.abs(u) <= p) {
|
|
3014
3024
|
const y = this.localToWorld(d.x, d.y);
|
|
@@ -3025,8 +3035,8 @@ class pt extends Q {
|
|
|
3025
3035
|
if (!this.isCropping) return !1;
|
|
3026
3036
|
const o = this.getCropBoxBounds();
|
|
3027
3037
|
if (!o) return !1;
|
|
3028
|
-
const
|
|
3029
|
-
return
|
|
3038
|
+
const s = this.worldToLocal(t, e);
|
|
3039
|
+
return s.x >= o.x && s.x <= o.x + o.width && s.y >= o.y && s.y <= o.y + o.height;
|
|
3030
3040
|
}
|
|
3031
3041
|
/**
|
|
3032
3042
|
* Update crop box (normalized 0-1 coordinates)
|
|
@@ -3036,46 +3046,46 @@ class pt extends Q {
|
|
|
3036
3046
|
* @param {number} cropHeight - Normalized height (0-1)
|
|
3037
3047
|
* @param {boolean} adjustPosition - Whether to adjust this.x, this.y to keep visual position stable (default: false)
|
|
3038
3048
|
*/
|
|
3039
|
-
updateCrop(t, e, o,
|
|
3040
|
-
let n = Math.max(0.1, Math.min(1, o)), h = Math.max(0.1, Math.min(1,
|
|
3049
|
+
updateCrop(t, e, o, s, i = !1) {
|
|
3050
|
+
let n = Math.max(0.1, Math.min(1, o)), h = Math.max(0.1, Math.min(1, s)), l = Math.max(0, Math.min(1 - n, t)), c = Math.max(0, Math.min(1 - h, e));
|
|
3041
3051
|
l + n > 1 && (n = 1 - l), c + h > 1 && (h = 1 - c);
|
|
3042
3052
|
let g = 0, d = 0;
|
|
3043
|
-
if (
|
|
3053
|
+
if (i) {
|
|
3044
3054
|
const f = this.transformData.cropX * this.transformData.width + this.transformData.cropWidth * this.transformData.width / 2, u = this.transformData.cropY * this.transformData.height + this.transformData.cropHeight * this.transformData.height / 2, m = l * this.transformData.width + n * this.transformData.width / 2, p = c * this.transformData.height + h * this.transformData.height / 2, y = m - f, x = p - u, b = Math.cos(D.toRadians(this.rotation)), S = Math.sin(D.toRadians(this.rotation));
|
|
3045
3055
|
g = y * b - x * S, d = y * S + x * b;
|
|
3046
3056
|
}
|
|
3047
|
-
this.transformData.cropX = l, this.transformData.cropY = c, this.transformData.cropWidth = n, this.transformData.cropHeight = h,
|
|
3057
|
+
this.transformData.cropX = l, this.transformData.cropY = c, this.transformData.cropWidth = n, this.transformData.cropHeight = h, i && (this.x += g, this.y += d);
|
|
3048
3058
|
}
|
|
3049
3059
|
/**
|
|
3050
3060
|
* Get the local position of the corner opposite to the given anchor
|
|
3051
3061
|
* Corners are relative to frame center
|
|
3052
3062
|
*/
|
|
3053
3063
|
getOppositeCornerLocalPosition(t, e, o) {
|
|
3054
|
-
const
|
|
3064
|
+
const s = e / 2, i = o / 2;
|
|
3055
3065
|
return {
|
|
3056
|
-
"top-left": { x:
|
|
3066
|
+
"top-left": { x: s, y: i },
|
|
3057
3067
|
// Opposite is bottom-right
|
|
3058
|
-
"top-right": { x: -
|
|
3068
|
+
"top-right": { x: -s, y: i },
|
|
3059
3069
|
// Opposite is bottom-left
|
|
3060
|
-
"bottom-left": { x:
|
|
3070
|
+
"bottom-left": { x: s, y: -i },
|
|
3061
3071
|
// Opposite is top-right
|
|
3062
|
-
"bottom-right": { x: -
|
|
3072
|
+
"bottom-right": { x: -s, y: -i },
|
|
3063
3073
|
// Opposite is top-left
|
|
3064
|
-
top: { x: 0, y:
|
|
3074
|
+
top: { x: 0, y: i },
|
|
3065
3075
|
// Opposite is bottom edge
|
|
3066
|
-
bottom: { x: 0, y: -
|
|
3076
|
+
bottom: { x: 0, y: -i },
|
|
3067
3077
|
// Opposite is top edge
|
|
3068
|
-
left: { x:
|
|
3078
|
+
left: { x: s, y: 0 },
|
|
3069
3079
|
// Opposite is right edge
|
|
3070
|
-
right: { x: -
|
|
3080
|
+
right: { x: -s, y: 0 },
|
|
3071
3081
|
// Opposite is left edge
|
|
3072
|
-
"middle-top": { x: 0, y:
|
|
3082
|
+
"middle-top": { x: 0, y: i },
|
|
3073
3083
|
// Opposite is bottom edge
|
|
3074
|
-
"middle-bottom": { x: 0, y: -
|
|
3084
|
+
"middle-bottom": { x: 0, y: -i },
|
|
3075
3085
|
// Opposite is top edge
|
|
3076
|
-
"middle-left": { x:
|
|
3086
|
+
"middle-left": { x: s, y: 0 },
|
|
3077
3087
|
// Opposite is right edge
|
|
3078
|
-
"middle-right": { x: -
|
|
3088
|
+
"middle-right": { x: -s, y: 0 }
|
|
3079
3089
|
// Opposite is left edge
|
|
3080
3090
|
}[t];
|
|
3081
3091
|
}
|
|
@@ -3084,7 +3094,7 @@ class pt extends Q {
|
|
|
3084
3094
|
* In crop mode, this.x/y is the crop center, not the frame center
|
|
3085
3095
|
*/
|
|
3086
3096
|
calculateFrameCenterFromCropCenter(t) {
|
|
3087
|
-
const e = C(t).width * C(t).cropWidth, o = C(t).height * C(t).cropHeight,
|
|
3097
|
+
const e = C(t).width * C(t).cropWidth, o = C(t).height * C(t).cropHeight, s = C(t).width / 2 - (C(t).cropX * C(t).width + e / 2), i = C(t).height / 2 - (C(t).cropY * C(t).height + o / 2), n = new R(t).localDeltaToWorld(s, i);
|
|
3088
3098
|
return {
|
|
3089
3099
|
x: t.x + n.dx,
|
|
3090
3100
|
y: t.y + n.dy
|
|
@@ -3098,10 +3108,10 @@ class pt extends Q {
|
|
|
3098
3108
|
t,
|
|
3099
3109
|
C(e).width,
|
|
3100
3110
|
C(e).height
|
|
3101
|
-
),
|
|
3111
|
+
), s = this.calculateFrameCenterFromCropCenter(e), a = new R(e).localDeltaToWorld(o.x, o.y);
|
|
3102
3112
|
return {
|
|
3103
|
-
x:
|
|
3104
|
-
y:
|
|
3113
|
+
x: s.x + a.dx,
|
|
3114
|
+
y: s.y + a.dy
|
|
3105
3115
|
};
|
|
3106
3116
|
}
|
|
3107
3117
|
/**
|
|
@@ -3109,15 +3119,15 @@ class pt extends Q {
|
|
|
3109
3119
|
* The opposite corner from the anchor stays fixed in world space
|
|
3110
3120
|
*/
|
|
3111
3121
|
calculateFrameCenterAfterResize(t, e, o) {
|
|
3112
|
-
const
|
|
3122
|
+
const s = this.getFixedCornerWorldPosition(e, o), i = C(o).width * t, a = i / this.imageAspectRatio, n = this.getOppositeCornerLocalPosition(e, i, a), l = new R({
|
|
3113
3123
|
x: 0,
|
|
3114
3124
|
// Will calculate frame center
|
|
3115
3125
|
y: 0,
|
|
3116
3126
|
rotation: o.rotation
|
|
3117
3127
|
}).localDeltaToWorld(n.x, n.y);
|
|
3118
3128
|
return {
|
|
3119
|
-
x:
|
|
3120
|
-
y:
|
|
3129
|
+
x: s.x - l.dx,
|
|
3130
|
+
y: s.y - l.dy
|
|
3121
3131
|
};
|
|
3122
3132
|
}
|
|
3123
3133
|
/**
|
|
@@ -3126,7 +3136,7 @@ class pt extends Q {
|
|
|
3126
3136
|
* would be positioned within the frame after resize.
|
|
3127
3137
|
*/
|
|
3128
3138
|
calculateCropStateAtScale(t, e, o) {
|
|
3129
|
-
const
|
|
3139
|
+
const s = C(o).width * t, i = s / this.imageAspectRatio, a = C(o).cropWidth * C(o).width, n = C(o).cropHeight * C(o).height, h = a / s, l = n / i, c = this.calculateFrameCenterAfterResize(t, e, o), g = {
|
|
3130
3140
|
x: o.x,
|
|
3131
3141
|
// In crop mode, this.x/y is the crop center
|
|
3132
3142
|
y: o.y
|
|
@@ -3134,7 +3144,7 @@ class pt extends Q {
|
|
|
3134
3144
|
x: c.x,
|
|
3135
3145
|
y: c.y,
|
|
3136
3146
|
rotation: o.rotation
|
|
3137
|
-
}).worldDeltaToLocal(d, f), p =
|
|
3147
|
+
}).worldDeltaToLocal(d, f), p = s / 2 + m.dx, y = i / 2 + m.dy, x = p / s - h / 2, b = y / i - l / 2;
|
|
3138
3148
|
return {
|
|
3139
3149
|
cropX: x,
|
|
3140
3150
|
cropY: b,
|
|
@@ -3146,20 +3156,20 @@ class pt extends Q {
|
|
|
3146
3156
|
* Check if a given scale keeps crop within frame bounds
|
|
3147
3157
|
*/
|
|
3148
3158
|
isScaleValidForCropBounds(t, e, o) {
|
|
3149
|
-
const
|
|
3150
|
-
if (
|
|
3159
|
+
const i = this.calculateCropStateAtScale(t, e, o);
|
|
3160
|
+
if (i.cropWidth > 1 + 1e-4 || i.cropHeight > 1 + 1e-4)
|
|
3151
3161
|
return !1;
|
|
3152
|
-
const a =
|
|
3162
|
+
const a = i.cropX, n = i.cropX + i.cropWidth, h = i.cropY, l = i.cropY + i.cropHeight;
|
|
3153
3163
|
return a >= -1e-4 && h >= -1e-4 && n <= 1 + 1e-4 && l <= 1 + 1e-4;
|
|
3154
3164
|
}
|
|
3155
3165
|
/**
|
|
3156
3166
|
* Calculate minimum scale that keeps crop within frame bounds
|
|
3157
3167
|
* Uses binary search to find the largest scale >= proposedScale that satisfies constraints
|
|
3158
3168
|
*/
|
|
3159
|
-
calculateMinScaleForCropBounds(t, e, o,
|
|
3169
|
+
calculateMinScaleForCropBounds(t, e, o, s) {
|
|
3160
3170
|
if (this.isScaleValidForCropBounds(o, t, e))
|
|
3161
3171
|
return o;
|
|
3162
|
-
let n = o, h =
|
|
3172
|
+
let n = o, h = s;
|
|
3163
3173
|
for (let l = 0; l < 20; l++) {
|
|
3164
3174
|
const c = (n + h) / 2;
|
|
3165
3175
|
if (this.isScaleValidForCropBounds(c, t, e) ? h = c : n = c, Math.abs(h - n) < 1e-4)
|
|
@@ -3172,15 +3182,15 @@ class pt extends Q {
|
|
|
3172
3182
|
*/
|
|
3173
3183
|
remapAnchorForFlips(t, e) {
|
|
3174
3184
|
let o = t;
|
|
3175
|
-
const
|
|
3176
|
-
return
|
|
3185
|
+
const s = C(e).flipHorizontal, i = C(e).flipVertical;
|
|
3186
|
+
return s && (o.includes("left") ? o = o.replace("left", "right") : o.includes("right") && (o = o.replace("right", "left"))), i && (o.includes("top") ? o = o.replace("top", "bottom") : o.includes("bottom") && (o = o.replace("bottom", "top"))), o;
|
|
3177
3187
|
}
|
|
3178
3188
|
/**
|
|
3179
3189
|
* Clone this element
|
|
3180
3190
|
*/
|
|
3181
3191
|
clone() {
|
|
3182
|
-
const t = this.toJSON(), { imageUrl: e, ...o } = t,
|
|
3183
|
-
return
|
|
3192
|
+
const t = this.toJSON(), { imageUrl: e, ...o } = t, s = new pt(o);
|
|
3193
|
+
return s.imageUrl = this.imageUrl, s.imageElement = this.imageElement, s.imageLoaded = this.imageLoaded, s.imageAspectRatio = this.imageAspectRatio, s.isCropping = this.isCropping, s.onLoadCallback = this.onLoadCallback, s.isSvg = this.isSvg, s.imageLoadState = this.imageLoadState, s.imageLoadError = this.imageLoadError, s.preserveDimensions = this.preserveDimensions, s;
|
|
3184
3194
|
}
|
|
3185
3195
|
/**
|
|
3186
3196
|
* Serialize to JSON
|
|
@@ -3200,6 +3210,8 @@ class pt extends Q {
|
|
|
3200
3210
|
// Explicitly include to ensure number type
|
|
3201
3211
|
imageUrl: this.imageUrl,
|
|
3202
3212
|
imageAspectRatio: this.imageAspectRatio,
|
|
3213
|
+
preserveDimensions: this.preserveDimensions,
|
|
3214
|
+
// dimension lock for cover crop must survive save→load
|
|
3203
3215
|
transformData: { ...this.transformData }
|
|
3204
3216
|
};
|
|
3205
3217
|
}
|
|
@@ -3236,7 +3248,7 @@ function Te() {
|
|
|
3236
3248
|
}
|
|
3237
3249
|
class P {
|
|
3238
3250
|
constructor(t = []) {
|
|
3239
|
-
this.spans = t.length > 0 ? t : [{ text: "", style: {} }], this.normalize();
|
|
3251
|
+
this.spans = t.length > 0 ? t.map((e) => ({ ...e, style: { ...e.style } })) : [{ text: "", style: {} }], this.normalize();
|
|
3240
3252
|
}
|
|
3241
3253
|
/**
|
|
3242
3254
|
* Create RichText from plain text string (no special formatting)
|
|
@@ -3281,31 +3293,31 @@ class P {
|
|
|
3281
3293
|
applyStyle(t, e, o) {
|
|
3282
3294
|
if (t >= e || t < 0 || e > this.getLength())
|
|
3283
3295
|
return;
|
|
3284
|
-
const
|
|
3285
|
-
let
|
|
3296
|
+
const s = [];
|
|
3297
|
+
let i = 0;
|
|
3286
3298
|
for (const a of this.spans) {
|
|
3287
|
-
const n =
|
|
3299
|
+
const n = i, h = i + a.text.length;
|
|
3288
3300
|
if (h <= t) {
|
|
3289
|
-
|
|
3301
|
+
s.push(a), i = h;
|
|
3290
3302
|
continue;
|
|
3291
3303
|
}
|
|
3292
3304
|
if (n >= e) {
|
|
3293
|
-
|
|
3305
|
+
s.push(a), i = h;
|
|
3294
3306
|
continue;
|
|
3295
3307
|
}
|
|
3296
3308
|
const l = Math.max(t, n), c = Math.min(e, h);
|
|
3297
|
-
l > n &&
|
|
3309
|
+
l > n && s.push({
|
|
3298
3310
|
text: a.text.substring(0, l - n),
|
|
3299
3311
|
style: a.style
|
|
3300
|
-
}),
|
|
3312
|
+
}), s.push({
|
|
3301
3313
|
text: a.text.substring(l - n, c - n),
|
|
3302
3314
|
style: { ...a.style, ...o }
|
|
3303
|
-
}), c < h &&
|
|
3315
|
+
}), c < h && s.push({
|
|
3304
3316
|
text: a.text.substring(c - n),
|
|
3305
3317
|
style: a.style
|
|
3306
|
-
}),
|
|
3318
|
+
}), i = h;
|
|
3307
3319
|
}
|
|
3308
|
-
this.spans =
|
|
3320
|
+
this.spans = s, this.normalize();
|
|
3309
3321
|
}
|
|
3310
3322
|
/**
|
|
3311
3323
|
* Insert text at a specific position with a given style
|
|
@@ -3315,24 +3327,24 @@ class P {
|
|
|
3315
3327
|
*/
|
|
3316
3328
|
insert(t, e, o) {
|
|
3317
3329
|
if (e.length === 0) return;
|
|
3318
|
-
const
|
|
3319
|
-
let
|
|
3330
|
+
const s = [];
|
|
3331
|
+
let i = 0;
|
|
3320
3332
|
for (const a of this.spans) {
|
|
3321
|
-
const n =
|
|
3322
|
-
if (t <= n &&
|
|
3333
|
+
const n = i, h = i + a.text.length;
|
|
3334
|
+
if (t <= n && s.length === 0 && s.push({ text: e, style: o }), t > n && t <= h) {
|
|
3323
3335
|
const l = t - n;
|
|
3324
|
-
|
|
3336
|
+
s.push({
|
|
3325
3337
|
text: a.text.substring(0, l),
|
|
3326
3338
|
style: a.style
|
|
3327
|
-
}),
|
|
3339
|
+
}), s.push({ text: e, style: o }), s.push({
|
|
3328
3340
|
text: a.text.substring(l),
|
|
3329
3341
|
style: a.style
|
|
3330
|
-
}),
|
|
3342
|
+
}), i = h;
|
|
3331
3343
|
continue;
|
|
3332
3344
|
}
|
|
3333
|
-
|
|
3345
|
+
s.push(a), i = h;
|
|
3334
3346
|
}
|
|
3335
|
-
t >= this.getLength() && !
|
|
3347
|
+
t >= this.getLength() && !s.some((a) => a.text === e) && s.push({ text: e, style: o }), this.spans = s, this.normalize();
|
|
3336
3348
|
}
|
|
3337
3349
|
/**
|
|
3338
3350
|
* Delete text in a character range
|
|
@@ -3343,28 +3355,28 @@ class P {
|
|
|
3343
3355
|
const o = this.getLength();
|
|
3344
3356
|
if (t = Math.max(0, Math.min(t, o)), e = Math.max(0, Math.min(e, o)), t >= e)
|
|
3345
3357
|
return;
|
|
3346
|
-
const
|
|
3347
|
-
let
|
|
3358
|
+
const s = [];
|
|
3359
|
+
let i = 0;
|
|
3348
3360
|
for (const a of this.spans) {
|
|
3349
|
-
const n =
|
|
3361
|
+
const n = i, h = i + a.text.length;
|
|
3350
3362
|
if (h <= t) {
|
|
3351
|
-
|
|
3363
|
+
s.push(a), i = h;
|
|
3352
3364
|
continue;
|
|
3353
3365
|
}
|
|
3354
3366
|
if (n >= e) {
|
|
3355
|
-
|
|
3367
|
+
s.push(a), i = h;
|
|
3356
3368
|
continue;
|
|
3357
3369
|
}
|
|
3358
3370
|
const l = Math.max(t, n), c = Math.min(e, h);
|
|
3359
|
-
l > n &&
|
|
3371
|
+
l > n && s.push({
|
|
3360
3372
|
text: a.text.substring(0, l - n),
|
|
3361
3373
|
style: a.style
|
|
3362
|
-
}), c < h &&
|
|
3374
|
+
}), c < h && s.push({
|
|
3363
3375
|
text: a.text.substring(c - n),
|
|
3364
3376
|
style: a.style
|
|
3365
|
-
}),
|
|
3377
|
+
}), i = h;
|
|
3366
3378
|
}
|
|
3367
|
-
this.spans =
|
|
3379
|
+
this.spans = s.length > 0 ? s : [{ text: "", style: {} }], this.normalize();
|
|
3368
3380
|
}
|
|
3369
3381
|
/**
|
|
3370
3382
|
* Normalize spans by:
|
|
@@ -3381,11 +3393,11 @@ class P {
|
|
|
3381
3393
|
const t = [];
|
|
3382
3394
|
let e = this.spans[0];
|
|
3383
3395
|
for (let o = 1; o < this.spans.length; o++) {
|
|
3384
|
-
const
|
|
3385
|
-
this.stylesEqual(e.style,
|
|
3386
|
-
text: e.text +
|
|
3396
|
+
const s = this.spans[o];
|
|
3397
|
+
this.stylesEqual(e.style, s.style) ? e = {
|
|
3398
|
+
text: e.text + s.text,
|
|
3387
3399
|
style: e.style
|
|
3388
|
-
} : (t.push(e), e =
|
|
3400
|
+
} : (t.push(e), e = s);
|
|
3389
3401
|
}
|
|
3390
3402
|
t.push(e), this.spans = t;
|
|
3391
3403
|
}
|
|
@@ -3421,7 +3433,7 @@ class P {
|
|
|
3421
3433
|
* Serialize to JSON
|
|
3422
3434
|
*/
|
|
3423
3435
|
toJSON() {
|
|
3424
|
-
return { spans: this.spans };
|
|
3436
|
+
return { spans: this.spans.map((t) => ({ ...t, style: { ...t.style } })) };
|
|
3425
3437
|
}
|
|
3426
3438
|
/**
|
|
3427
3439
|
* Deserialize from JSON
|
|
@@ -3513,8 +3525,8 @@ class q extends Q {
|
|
|
3513
3525
|
* handled by SelectionRenderer and HoverRenderer.
|
|
3514
3526
|
*/
|
|
3515
3527
|
render(t, e = !1, o = !1) {
|
|
3516
|
-
const
|
|
3517
|
-
this.opacity !== void 0 && this.opacity !== 1 && (t.globalAlpha = this.opacity), gt(this.transformType)(t, this.toJSON()), t.globalAlpha =
|
|
3528
|
+
const s = t.globalAlpha;
|
|
3529
|
+
this.opacity !== void 0 && this.opacity !== 1 && (t.globalAlpha = this.opacity), gt(this.transformType)(t, this.toJSON()), t.globalAlpha = s;
|
|
3518
3530
|
}
|
|
3519
3531
|
/**
|
|
3520
3532
|
* Serialize to JSON
|
|
@@ -3590,8 +3602,8 @@ class q extends Q {
|
|
|
3590
3602
|
* Apply character-level formatting to a text range
|
|
3591
3603
|
*/
|
|
3592
3604
|
applyFormatting(t, e, o) {
|
|
3593
|
-
const
|
|
3594
|
-
|
|
3605
|
+
const s = this.getRichText();
|
|
3606
|
+
s.applyStyle(t, e, o), this.text = s.getText();
|
|
3595
3607
|
}
|
|
3596
3608
|
/**
|
|
3597
3609
|
* Update font size
|
|
@@ -3607,15 +3619,15 @@ class q extends Q {
|
|
|
3607
3619
|
const e = this.color;
|
|
3608
3620
|
if (this.color = t, this.richText)
|
|
3609
3621
|
for (let o = 0; o < this.richText.spans.length; o++) {
|
|
3610
|
-
const
|
|
3611
|
-
(
|
|
3622
|
+
const s = this.richText.spans[o];
|
|
3623
|
+
(s.style.color === void 0 || s.style.color === e) && (s.style.color = t);
|
|
3612
3624
|
}
|
|
3613
3625
|
}
|
|
3614
3626
|
/**
|
|
3615
3627
|
* Handle resize transform
|
|
3616
3628
|
* Must be implemented by subclasses
|
|
3617
3629
|
*/
|
|
3618
|
-
resize(t, e, o,
|
|
3630
|
+
resize(t, e, o, s) {
|
|
3619
3631
|
throw new Error("resize() must be implemented by subclass");
|
|
3620
3632
|
}
|
|
3621
3633
|
/**
|
|
@@ -3643,19 +3655,19 @@ function yt() {
|
|
|
3643
3655
|
return ht;
|
|
3644
3656
|
}
|
|
3645
3657
|
function at(r, t, e = !1, o = !1) {
|
|
3646
|
-
const
|
|
3647
|
-
return o &&
|
|
3658
|
+
const s = [];
|
|
3659
|
+
return o && s.push("italic"), e && s.push("bold"), s.push(`${r}px`), s.push(t), s.join(" ");
|
|
3648
3660
|
}
|
|
3649
|
-
function vt(r, t, e, o,
|
|
3661
|
+
function vt(r, t, e, o, s = !1, i = !1, a, n = !1) {
|
|
3650
3662
|
const l = yt().getContext("2d");
|
|
3651
|
-
if (l.font = at(e, o,
|
|
3663
|
+
if (l.font = at(e, o, s, i), r.trim().length === 0)
|
|
3652
3664
|
return [r];
|
|
3653
3665
|
if (r.includes(`
|
|
3654
3666
|
`)) {
|
|
3655
3667
|
const M = r.split(`
|
|
3656
3668
|
`), k = [];
|
|
3657
3669
|
for (let I = 0; I < M.length; I++) {
|
|
3658
|
-
const O = M[I], B = vt(O, t, e, o,
|
|
3670
|
+
const O = M[I], B = vt(O, t, e, o, s, i, void 0, n);
|
|
3659
3671
|
k.push(...B);
|
|
3660
3672
|
}
|
|
3661
3673
|
return k;
|
|
@@ -3705,25 +3717,25 @@ function vt(r, t, e, o, i = !1, s = !1, a, n = !1) {
|
|
|
3705
3717
|
}
|
|
3706
3718
|
return w;
|
|
3707
3719
|
}
|
|
3708
|
-
function Ot(r, t, e, o = !1,
|
|
3720
|
+
function Ot(r, t, e, o = !1, s = !1) {
|
|
3709
3721
|
const a = yt().getContext("2d");
|
|
3710
|
-
return a.font = at(t, e, o,
|
|
3722
|
+
return a.font = at(t, e, o, s), a.measureText(r).width;
|
|
3711
3723
|
}
|
|
3712
3724
|
function Tt(r, t, e = !1, o = !1) {
|
|
3713
|
-
const
|
|
3714
|
-
|
|
3715
|
-
const n =
|
|
3725
|
+
const i = yt().getContext("2d");
|
|
3726
|
+
i.font = at(r, t, e, o);
|
|
3727
|
+
const n = i.measureText("ÁÉÍgjpqy"), h = n.actualBoundingBoxAscent || r * 0.8, l = n.actualBoundingBoxDescent || r * 0.2, c = h + l;
|
|
3716
3728
|
return { ascent: h, descent: l, height: c };
|
|
3717
3729
|
}
|
|
3718
|
-
function Bt(r, t, e, o,
|
|
3719
|
-
const h = vt(r, t, e, o,
|
|
3730
|
+
function Bt(r, t, e, o, s = !1, i = !1, a, n = !1) {
|
|
3731
|
+
const h = vt(r, t, e, o, s, i, a, n), l = r.includes(`
|
|
3720
3732
|
`), c = h.map((x, b) => ({
|
|
3721
3733
|
isParagraphStart: !l && b === 0,
|
|
3722
3734
|
isParagraphEnd: !l && b === h.length - 1
|
|
3723
3735
|
})), d = yt().getContext("2d");
|
|
3724
|
-
d.font = at(e, o,
|
|
3736
|
+
d.font = at(e, o, s, i);
|
|
3725
3737
|
let f = 0;
|
|
3726
|
-
const u = Tt(e, o,
|
|
3738
|
+
const u = Tt(e, o, s, i);
|
|
3727
3739
|
let m = 0;
|
|
3728
3740
|
h.forEach((x, b) => {
|
|
3729
3741
|
const S = c[b].isParagraphStart, v = c[b].isParagraphEnd;
|
|
@@ -3769,7 +3781,7 @@ function ve() {
|
|
|
3769
3781
|
return lt;
|
|
3770
3782
|
}
|
|
3771
3783
|
function Fe(r, t, e) {
|
|
3772
|
-
const o = ve(),
|
|
3784
|
+
const o = ve(), s = [], i = (p, y) => {
|
|
3773
3785
|
const x = y.fontSize || e.fontSize, b = y.fontFamily || e.fontFamily, S = y.bold !== void 0 ? y.bold : e.bold || !1, v = y.italic !== void 0 ? y.italic : e.italic || !1;
|
|
3774
3786
|
return o.font = at(x, b, S, v), o.measureText(p).width;
|
|
3775
3787
|
}, a = (p, y) => p.fontSize === y.fontSize && p.fontFamily === y.fontFamily && p.color === y.color && p.bold === y.bold && p.italic === y.italic && p.underline === y.underline && p.strikethrough === y.strikethrough, n = [];
|
|
@@ -3791,7 +3803,7 @@ function Fe(r, t, e) {
|
|
|
3791
3803
|
g.length > 0 && c.push({ text: g, startIdx: d, endIdx: h.length - 1 });
|
|
3792
3804
|
let f = [], u = 0;
|
|
3793
3805
|
const m = () => {
|
|
3794
|
-
f.length > 0 && (
|
|
3806
|
+
f.length > 0 && (s.push(f), f = [], u = 0);
|
|
3795
3807
|
};
|
|
3796
3808
|
return c.forEach((p, y) => {
|
|
3797
3809
|
const x = [];
|
|
@@ -3801,7 +3813,7 @@ function Fe(r, t, e) {
|
|
|
3801
3813
|
T !== b ? (x.push({ text: S, style: n[b].style }), S = h[w], b = T) : S += h[w];
|
|
3802
3814
|
}
|
|
3803
3815
|
S.length > 0 && x.push({ text: S, style: n[b].style });
|
|
3804
|
-
const v = x.reduce((w, T) => w +
|
|
3816
|
+
const v = x.reduce((w, T) => w + i(T.text, T.style), 0);
|
|
3805
3817
|
if (p.text === " ") {
|
|
3806
3818
|
if (f.length > 0) {
|
|
3807
3819
|
const w = f[f.length - 1];
|
|
@@ -3815,7 +3827,7 @@ function Fe(r, t, e) {
|
|
|
3815
3827
|
const T = Array.from(w.text);
|
|
3816
3828
|
let F = "";
|
|
3817
3829
|
for (const A of T) {
|
|
3818
|
-
const M =
|
|
3830
|
+
const M = i(A, w.style);
|
|
3819
3831
|
if (u + M > t && u > 0) {
|
|
3820
3832
|
if (F.length > 0) {
|
|
3821
3833
|
if (f.length > 0) {
|
|
@@ -3844,27 +3856,27 @@ function Fe(r, t, e) {
|
|
|
3844
3856
|
} else
|
|
3845
3857
|
f.push({ ...w });
|
|
3846
3858
|
}), u += v;
|
|
3847
|
-
}), m(),
|
|
3859
|
+
}), m(), s.length === 0 && s.push([]), s;
|
|
3848
3860
|
}
|
|
3849
3861
|
function Me(r) {
|
|
3850
3862
|
const t = [];
|
|
3851
3863
|
let e = [];
|
|
3852
3864
|
return r.spans.forEach((o) => {
|
|
3853
|
-
const
|
|
3865
|
+
const s = o.text.split(`
|
|
3854
3866
|
`);
|
|
3855
|
-
|
|
3856
|
-
|
|
3867
|
+
s.forEach((i, a) => {
|
|
3868
|
+
i.length > 0 && e.push({ text: i, style: o.style }), a < s.length - 1 && (t.push(e), e = []);
|
|
3857
3869
|
});
|
|
3858
3870
|
}), e.length > 0 && t.push(e), t.length === 0 && t.push([]), t;
|
|
3859
3871
|
}
|
|
3860
|
-
function
|
|
3872
|
+
function st(r) {
|
|
3861
3873
|
return typeof r.width == "number" ? r.width : void 0;
|
|
3862
3874
|
}
|
|
3863
3875
|
function Ut(r, t) {
|
|
3864
3876
|
r.width = t;
|
|
3865
3877
|
}
|
|
3866
3878
|
function Ae(r, t, e) {
|
|
3867
|
-
const o = e.transformData,
|
|
3879
|
+
const o = e.transformData, s = st(o), i = s !== void 0 ? s : e.width ?? 0, a = t / i, n = e.fontSize ?? r.fontSize, h = n * a;
|
|
3868
3880
|
let l;
|
|
3869
3881
|
if (h < 16 ? l = Math.round(h) : l = Math.round(h * 2) / 2, r.setFontSize(l), e.richText && e.richText instanceof P && typeof r.setRichText == "function") {
|
|
3870
3882
|
const f = e.richText.clone();
|
|
@@ -3876,8 +3888,8 @@ function Ae(r, t, e) {
|
|
|
3876
3888
|
r.setRichText(f);
|
|
3877
3889
|
}
|
|
3878
3890
|
const c = r.transformData;
|
|
3879
|
-
if (
|
|
3880
|
-
const d = n > 0 ? l / n : a, f =
|
|
3891
|
+
if (st(c) !== void 0 && s !== void 0) {
|
|
3892
|
+
const d = n > 0 ? l / n : a, f = s * d;
|
|
3881
3893
|
Ut(c, Math.max(20, Math.ceil(f)));
|
|
3882
3894
|
}
|
|
3883
3895
|
}
|
|
@@ -3885,16 +3897,16 @@ function De(r, t, e, o) {
|
|
|
3885
3897
|
if (t !== "middle-left" && t !== "middle-right")
|
|
3886
3898
|
return;
|
|
3887
3899
|
r.fontSize = o.fontSize ?? r.fontSize;
|
|
3888
|
-
const
|
|
3889
|
-
if (
|
|
3890
|
-
Ut(
|
|
3891
|
-
const a = D.toRadiansInverse(r.rotation), n = Math.cos(a), h = Math.sin(a), l = o.transformData, g =
|
|
3900
|
+
const s = r.transformData;
|
|
3901
|
+
if (st(s) !== void 0) {
|
|
3902
|
+
Ut(s, Math.max(Yt, e));
|
|
3903
|
+
const a = D.toRadiansInverse(r.rotation), n = Math.cos(a), h = Math.sin(a), l = o.transformData, g = st(l) ?? o.width ?? 0, f = (st(s) ?? 0) - g;
|
|
3892
3904
|
t === "middle-left" ? (r.x = o.x - f / 2 * n, r.y = o.y - f / 2 * h) : t === "middle-right" && (r.x = o.x + f / 2 * n, r.y = o.y + f / 2 * h);
|
|
3893
3905
|
}
|
|
3894
3906
|
}
|
|
3895
|
-
function Gt(r, t, e, o,
|
|
3896
|
-
const
|
|
3897
|
-
|
|
3907
|
+
function Gt(r, t, e, o, s) {
|
|
3908
|
+
const i = t.includes("top") || t.includes("bottom"), a = t.includes("middle");
|
|
3909
|
+
i ? Ae(r, e, s) : a && De(r, t, e, s);
|
|
3898
3910
|
}
|
|
3899
3911
|
class Ie extends q {
|
|
3900
3912
|
// Temporary property used during resize operations only
|
|
@@ -3915,7 +3927,7 @@ class Ie extends q {
|
|
|
3915
3927
|
* Returns the total height based on the tallest font in each line
|
|
3916
3928
|
*/
|
|
3917
3929
|
calculateRichTextHeight() {
|
|
3918
|
-
const t = this.getRichText(), e = this.transformData.width - j * 2, o = Me(t),
|
|
3930
|
+
const t = this.getRichText(), e = this.transformData.width - j * 2, o = Me(t), s = [];
|
|
3919
3931
|
if (o.forEach((h) => {
|
|
3920
3932
|
Fe(h, e, {
|
|
3921
3933
|
fontSize: this.fontSize,
|
|
@@ -3923,22 +3935,22 @@ class Ie extends q {
|
|
|
3923
3935
|
bold: this.bold,
|
|
3924
3936
|
italic: this.italic
|
|
3925
3937
|
}).forEach((c) => {
|
|
3926
|
-
|
|
3938
|
+
s.push(c);
|
|
3927
3939
|
});
|
|
3928
|
-
}),
|
|
3940
|
+
}), s.length === 0)
|
|
3929
3941
|
return 0;
|
|
3930
|
-
let
|
|
3931
|
-
|
|
3942
|
+
let i = 0, a = 0;
|
|
3943
|
+
s.forEach((h) => {
|
|
3932
3944
|
h.forEach((l) => {
|
|
3933
3945
|
const c = l.style.fontSize !== void 0 ? l.style.fontSize : this.fontSize, g = l.style.fontFamily !== void 0 ? l.style.fontFamily : this.fontFamily, d = l.style.bold !== void 0 ? l.style.bold : this.bold, f = l.style.italic !== void 0 ? l.style.italic : this.italic, u = Tt(c, g, d, f);
|
|
3934
|
-
|
|
3946
|
+
i = Math.max(i, u.height), a = Math.max(a, u.ascent);
|
|
3935
3947
|
});
|
|
3936
3948
|
});
|
|
3937
3949
|
const n = this.fontSize * Xt;
|
|
3938
|
-
if (
|
|
3939
|
-
return
|
|
3950
|
+
if (s.length === 1)
|
|
3951
|
+
return i;
|
|
3940
3952
|
{
|
|
3941
|
-
const h = Tt(this.fontSize, this.fontFamily, this.bold, this.italic), l = (
|
|
3953
|
+
const h = Tt(this.fontSize, this.fontFamily, this.bold, this.italic), l = (s.length - 1) * n + h.height, c = Math.max(0, a - h.ascent), g = Math.max(0, i - a - (h.height - h.ascent));
|
|
3942
3954
|
return l + c + g;
|
|
3943
3955
|
}
|
|
3944
3956
|
}
|
|
@@ -4023,13 +4035,13 @@ class Ie extends q {
|
|
|
4023
4035
|
*/
|
|
4024
4036
|
render(t, e = !1, o = !1) {
|
|
4025
4037
|
var n;
|
|
4026
|
-
const
|
|
4027
|
-
if (
|
|
4028
|
-
this.renderWithOffscreen(t,
|
|
4038
|
+
const s = this.opacity ?? 1, i = !!((n = this.stroke) != null && n.enabled);
|
|
4039
|
+
if (s < 1 && i) {
|
|
4040
|
+
this.renderWithOffscreen(t, s);
|
|
4029
4041
|
return;
|
|
4030
4042
|
}
|
|
4031
4043
|
const a = t.globalAlpha;
|
|
4032
|
-
|
|
4044
|
+
s !== 1 && (t.globalAlpha = s), gt("custom")(t, this.toJSON()), t.globalAlpha = a;
|
|
4033
4045
|
}
|
|
4034
4046
|
/**
|
|
4035
4047
|
* Render stroke+fill to an offscreen canvas at full opacity, then composite
|
|
@@ -4037,7 +4049,7 @@ class Ie extends q {
|
|
|
4037
4049
|
*/
|
|
4038
4050
|
renderWithOffscreen(t, e) {
|
|
4039
4051
|
var d;
|
|
4040
|
-
const
|
|
4052
|
+
const s = (((d = this.stroke) == null ? void 0 : d.width) || 0) + 20, i = this.getVisualBoundingBox(), a = Math.ceil(i.width + s * 2), n = Math.ceil(i.height + s * 2), h = document.createElement("canvas");
|
|
4041
4053
|
h.width = a, h.height = n;
|
|
4042
4054
|
const l = h.getContext("2d");
|
|
4043
4055
|
if (!l) {
|
|
@@ -4045,7 +4057,7 @@ class Ie extends q {
|
|
|
4045
4057
|
t.globalAlpha = e, gt("custom")(t, this.toJSON()), t.globalAlpha = f;
|
|
4046
4058
|
return;
|
|
4047
4059
|
}
|
|
4048
|
-
const c =
|
|
4060
|
+
const c = i.x + i.width / 2, g = i.y + i.height / 2;
|
|
4049
4061
|
l.translate(a / 2 - c, n / 2 - g), gt("custom")(l, this.toJSON()), t.save(), t.globalAlpha = e, t.drawImage(h, c - a / 2, g - n / 2), t.restore();
|
|
4050
4062
|
}
|
|
4051
4063
|
/**
|
|
@@ -4060,8 +4072,8 @@ class Ie extends q {
|
|
|
4060
4072
|
* Corner handles: uniform scale (fontSize and width both change) - line count locked
|
|
4061
4073
|
* Side handles: only width changes - text re-wraps naturally
|
|
4062
4074
|
*/
|
|
4063
|
-
resize(t, e, o,
|
|
4064
|
-
if (t === "top-left" || t === "top-right" || t === "bottom-left" || t === "bottom-right" || (this._lockedLineCount = void 0), Gt(this, t, e, o,
|
|
4075
|
+
resize(t, e, o, s) {
|
|
4076
|
+
if (t === "top-left" || t === "top-right" || t === "bottom-left" || t === "bottom-right" || (this._lockedLineCount = void 0), Gt(this, t, e, o, s), this._lockedLineCount !== void 0 && this._lockedLineCount > 0) {
|
|
4065
4077
|
const n = Ot(this.text, this.fontSize, this.fontFamily, this.bold, this.italic) / this._lockedLineCount + j * 2;
|
|
4066
4078
|
this.transformData.width < n && (this.transformData.width = Math.ceil(n));
|
|
4067
4079
|
}
|
|
@@ -4100,32 +4112,33 @@ class Ie extends q {
|
|
|
4100
4112
|
transformType: "custom",
|
|
4101
4113
|
transformData: {
|
|
4102
4114
|
type: "custom",
|
|
4103
|
-
|
|
4115
|
+
// Copy point objects so serialized output never aliases the live array
|
|
4116
|
+
controlPoints: this.transformData.controlPoints.map((e) => ({ ...e })),
|
|
4104
4117
|
width: this.transformData.width
|
|
4105
4118
|
}
|
|
4106
4119
|
};
|
|
4107
4120
|
}
|
|
4108
4121
|
}
|
|
4109
4122
|
function ke(r, t, e, o) {
|
|
4110
|
-
const
|
|
4123
|
+
const s = D.toRadians(o), i = Math.cos(s), a = Math.sin(s);
|
|
4111
4124
|
let n = 0, h = 0;
|
|
4112
4125
|
e === "top-left" ? (n = r.width, h = r.height) : e === "top-right" ? (n = 0, h = r.height) : e === "bottom-left" ? (n = r.width, h = 0) : e === "bottom-right" && (n = 0, h = 0);
|
|
4113
|
-
const l = r.x + (n *
|
|
4126
|
+
const l = r.x + (n * i - h * a), c = r.y + (n * a + h * i);
|
|
4114
4127
|
let g = 0, d = 0;
|
|
4115
4128
|
e === "top-left" ? (g = t.width, d = t.height) : e === "top-right" ? (g = 0, d = t.height) : e === "bottom-left" ? (g = t.width, d = 0) : e === "bottom-right" && (g = 0, d = 0);
|
|
4116
|
-
const f = l - (g *
|
|
4129
|
+
const f = l - (g * i - d * a), u = c - (g * a + d * i);
|
|
4117
4130
|
return { x: f, y: u };
|
|
4118
4131
|
}
|
|
4119
4132
|
function No(r, t, e, o = 1) {
|
|
4120
|
-
const
|
|
4133
|
+
const s = r.width / 2, i = r.height + le / o, a = r.x + s, n = r.y + i, h = D.toRadians(t), l = Math.cos(h), c = Math.sin(h), g = a - e.x, d = n - e.y, f = g * l - d * c, u = g * c + d * l;
|
|
4121
4134
|
return {
|
|
4122
4135
|
x: e.x + f,
|
|
4123
4136
|
y: e.y + u
|
|
4124
4137
|
};
|
|
4125
4138
|
}
|
|
4126
4139
|
function Uo(r, t, e) {
|
|
4127
|
-
const o = D.toRadians(t),
|
|
4128
|
-
const d = r.x + c, f = r.y + g, u = d - e.x, m = f - e.y, p = u *
|
|
4140
|
+
const o = D.toRadians(t), s = Math.cos(o), i = Math.sin(o), a = (c, g) => {
|
|
4141
|
+
const d = r.x + c, f = r.y + g, u = d - e.x, m = f - e.y, p = u * s - m * i, y = u * i + m * s;
|
|
4129
4142
|
return {
|
|
4130
4143
|
x: e.x + p,
|
|
4131
4144
|
y: e.y + y
|
|
@@ -4160,16 +4173,16 @@ function Uo(r, t, e) {
|
|
|
4160
4173
|
l("edge", "middle-bottom", n / 2, h)
|
|
4161
4174
|
];
|
|
4162
4175
|
}
|
|
4163
|
-
function Go(r, t, e, o,
|
|
4164
|
-
const
|
|
4165
|
-
return
|
|
4176
|
+
function Go(r, t, e, o, s) {
|
|
4177
|
+
const i = r - e, a = t - o;
|
|
4178
|
+
return i * i + a * a <= s * s;
|
|
4166
4179
|
}
|
|
4167
4180
|
function $o(r, t, e, o) {
|
|
4168
|
-
const
|
|
4181
|
+
const s = D.toRadiansInverse(o), i = Math.cos(s), a = Math.sin(s), n = r - e.x, h = t - e.y, l = n * i - h * a, c = n * a + h * i;
|
|
4169
4182
|
return l >= 0 && l <= e.width && c >= 0 && c <= e.height;
|
|
4170
4183
|
}
|
|
4171
|
-
function tt(r, t, e = "Arial", o = !1,
|
|
4172
|
-
const a = document.createElement("canvas").getContext("2d"), n = o ? "bold" : "normal", h =
|
|
4184
|
+
function tt(r, t, e = "Arial", o = !1, s = !1) {
|
|
4185
|
+
const a = document.createElement("canvas").getContext("2d"), n = o ? "bold" : "normal", h = s ? "italic" : "normal";
|
|
4173
4186
|
return a.font = `${h} ${n} ${t}px ${e}`, a.measureText(r).width;
|
|
4174
4187
|
}
|
|
4175
4188
|
function Vo(r) {
|
|
@@ -4184,11 +4197,11 @@ function Jo(r, t, e, o) {
|
|
|
4184
4197
|
function qo(r, t, e) {
|
|
4185
4198
|
return Math.abs(r - t) <= e;
|
|
4186
4199
|
}
|
|
4187
|
-
function Ee(r, t, e, o,
|
|
4200
|
+
function Ee(r, t, e, o, s, i = 0, a = "") {
|
|
4188
4201
|
const n = r - e, h = t - o;
|
|
4189
4202
|
let l = Math.atan2(h, n) * (180 / Math.PI);
|
|
4190
|
-
if (l = (l % 360 + 360) % 360,
|
|
4191
|
-
if (Math.abs(
|
|
4203
|
+
if (l = (l % 360 + 360) % 360, s === "corner") {
|
|
4204
|
+
if (Math.abs(i) < 0.1) {
|
|
4192
4205
|
if (a === "top-left" || a === "bottom-right")
|
|
4193
4206
|
return "nwse-resize";
|
|
4194
4207
|
if (a === "top-right" || a === "bottom-left")
|
|
@@ -4209,7 +4222,7 @@ function Oe(r) {
|
|
|
4209
4222
|
}
|
|
4210
4223
|
function jo(r, t, e = []) {
|
|
4211
4224
|
const o = Oe(r);
|
|
4212
|
-
r.lineWidth = o > 0 ? t / o : t, e.length > 0 && r.setLineDash(o > 0 ? e.map((
|
|
4225
|
+
r.lineWidth = o > 0 ? t / o : t, e.length > 0 && r.setLineDash(o > 0 ? e.map((s) => s / o) : e);
|
|
4213
4226
|
}
|
|
4214
4227
|
class Be extends q {
|
|
4215
4228
|
constructor(t = {}) {
|
|
@@ -4241,11 +4254,11 @@ class Be extends q {
|
|
|
4241
4254
|
* For circular text, calculate the arc bounds where text actually appears
|
|
4242
4255
|
*/
|
|
4243
4256
|
getVisualBoundingBox() {
|
|
4244
|
-
const t = this.transformData.radius * this.transformData.scale, e = this.fontSize * this.transformData.scale,
|
|
4257
|
+
const t = this.transformData.radius * this.transformData.scale, e = this.fontSize * this.transformData.scale, s = tt(this.text, e, this.fontFamily, this.bold, this.italic) / t, i = -Math.PI / 2 - s / 2, a = -Math.PI / 2 + s / 2, n = t > e / 2 ? t - e / 2 : t * 0.1, h = t + e / 2;
|
|
4245
4258
|
let l = 1 / 0, c = -1 / 0, g = 1 / 0, d = -1 / 0;
|
|
4246
4259
|
const f = 10;
|
|
4247
4260
|
for (let u = 0; u <= f; u++) {
|
|
4248
|
-
const m =
|
|
4261
|
+
const m = i + (a - i) * (u / f), p = this.x + Math.cos(m) * n, y = this.y + Math.sin(m) * n, x = this.x + Math.cos(m) * h, b = this.y + Math.sin(m) * h;
|
|
4249
4262
|
l = Math.min(l, p, x), c = Math.max(c, p, x), g = Math.min(g, y, b), d = Math.max(d, y, b);
|
|
4250
4263
|
}
|
|
4251
4264
|
return {
|
|
@@ -4264,15 +4277,15 @@ class Be extends q {
|
|
|
4264
4277
|
* Handle resize
|
|
4265
4278
|
* For circle, we maintain uniform scale and keep scale on the transform
|
|
4266
4279
|
*/
|
|
4267
|
-
resize(t, e, o,
|
|
4268
|
-
const
|
|
4280
|
+
resize(t, e, o, s) {
|
|
4281
|
+
const i = s.transformData, a = (e + o) / 2, n = (s.width + s.height) / 2, h = a / n, l = i.scale * h, c = Math.max(0.1, Math.min(10, l));
|
|
4269
4282
|
this.transformData.scale = c;
|
|
4270
4283
|
const g = this.getBoundingBox(), d = ke(
|
|
4271
4284
|
{
|
|
4272
|
-
x:
|
|
4273
|
-
y:
|
|
4274
|
-
width:
|
|
4275
|
-
height:
|
|
4285
|
+
x: s.x - i.radius * i.scale,
|
|
4286
|
+
y: s.y - i.radius * i.scale,
|
|
4287
|
+
width: i.radius * 2 * i.scale,
|
|
4288
|
+
height: i.radius * 2 * i.scale
|
|
4276
4289
|
},
|
|
4277
4290
|
{ width: g.width, height: g.height },
|
|
4278
4291
|
t,
|
|
@@ -4361,10 +4374,10 @@ class Re extends q {
|
|
|
4361
4374
|
};
|
|
4362
4375
|
}
|
|
4363
4376
|
getVisualBoundingBox() {
|
|
4364
|
-
const t = this.text.split(""), e = t.map((u) => tt(u, this.fontSize, this.fontFamily)), o = e.reduce((u, m) => u + m, 0),
|
|
4377
|
+
const t = this.text.split(""), e = t.map((u) => tt(u, this.fontSize, this.fontFamily)), o = e.reduce((u, m) => u + m, 0), s = this.transformData.width / 2, i = 0.3, n = this.fontSize / 2;
|
|
4365
4378
|
let h = 1 / 0, l = -1 / 0, c = 1 / 0, g = -1 / 0, d = -o / 2;
|
|
4366
4379
|
t.forEach((u, m) => {
|
|
4367
|
-
const p = e[m], y = d + p / 2, x = y /
|
|
4380
|
+
const p = e[m], y = d + p / 2, x = y / s, b = (Math.pow(x, 2) - 1) * this.transformData.archHeight * this.fontSize, S = 2 * x * this.transformData.archHeight;
|
|
4368
4381
|
[
|
|
4369
4382
|
{ x: -p / 2, y: -n },
|
|
4370
4383
|
// top-left
|
|
@@ -4375,7 +4388,7 @@ class Re extends q {
|
|
|
4375
4388
|
{ x: p / 2, y: n }
|
|
4376
4389
|
// bottom-right
|
|
4377
4390
|
].forEach((w) => {
|
|
4378
|
-
const T = w.x, F = w.y + S *
|
|
4391
|
+
const T = w.x, F = w.y + S * i * w.x, A = y + T, M = b + F;
|
|
4379
4392
|
h = Math.min(h, A), l = Math.max(l, A), c = Math.min(c, M), g = Math.max(g, M);
|
|
4380
4393
|
}), d += p;
|
|
4381
4394
|
});
|
|
@@ -4387,22 +4400,22 @@ class Re extends q {
|
|
|
4387
4400
|
height: g - c
|
|
4388
4401
|
};
|
|
4389
4402
|
}
|
|
4390
|
-
resize(t, e, o,
|
|
4391
|
-
const
|
|
4392
|
-
if (
|
|
4393
|
-
const h = e /
|
|
4403
|
+
resize(t, e, o, s) {
|
|
4404
|
+
const i = t.includes("top") || t.includes("bottom"), a = t.includes("middle"), n = s.transformData;
|
|
4405
|
+
if (i) {
|
|
4406
|
+
const h = e / s.width, l = s.fontSize * h;
|
|
4394
4407
|
this.setFontSize(l);
|
|
4395
4408
|
const c = n.width * h;
|
|
4396
4409
|
this.transformData.width = Math.max(50, c);
|
|
4397
4410
|
} else if (a && (t === "middle-left" || t === "middle-right")) {
|
|
4398
|
-
this.fontSize =
|
|
4399
|
-
const h = e -
|
|
4411
|
+
this.fontSize = s.fontSize, this.transformData.width = Math.max(50, e);
|
|
4412
|
+
const h = e - s.width, l = this.rotation * Math.PI / 180, c = Math.cos(l), g = Math.sin(l);
|
|
4400
4413
|
if (t === "middle-left") {
|
|
4401
4414
|
const d = -h / 2;
|
|
4402
|
-
this.x =
|
|
4415
|
+
this.x = s.x + d * c, this.y = s.y + d * g;
|
|
4403
4416
|
} else if (t === "middle-right") {
|
|
4404
4417
|
const d = h / 2;
|
|
4405
|
-
this.x =
|
|
4418
|
+
this.x = s.x + d * c, this.y = s.y + d * g;
|
|
4406
4419
|
}
|
|
4407
4420
|
}
|
|
4408
4421
|
}
|
|
@@ -4434,7 +4447,7 @@ class Re extends q {
|
|
|
4434
4447
|
};
|
|
4435
4448
|
}
|
|
4436
4449
|
}
|
|
4437
|
-
const
|
|
4450
|
+
const it = {
|
|
4438
4451
|
amplitude: 0.2,
|
|
4439
4452
|
// 20% - subtle wave effect
|
|
4440
4453
|
frequency: 1.2,
|
|
@@ -4459,9 +4472,9 @@ class We extends q {
|
|
|
4459
4472
|
const e = t.transformData;
|
|
4460
4473
|
this.transformData = {
|
|
4461
4474
|
type: "wave",
|
|
4462
|
-
amplitude: (e == null ? void 0 : e.amplitude) ??
|
|
4463
|
-
frequency: (e == null ? void 0 : e.frequency) ??
|
|
4464
|
-
width: (e == null ? void 0 : e.width) ??
|
|
4475
|
+
amplitude: (e == null ? void 0 : e.amplitude) ?? it.amplitude,
|
|
4476
|
+
frequency: (e == null ? void 0 : e.frequency) ?? it.frequency,
|
|
4477
|
+
width: (e == null ? void 0 : e.width) ?? it.width
|
|
4465
4478
|
};
|
|
4466
4479
|
}
|
|
4467
4480
|
getBoundingBox() {
|
|
@@ -4474,18 +4487,18 @@ class We extends q {
|
|
|
4474
4487
|
};
|
|
4475
4488
|
}
|
|
4476
4489
|
getVisualBoundingBox() {
|
|
4477
|
-
const t = this.text.split(""), e = t.map((d) => tt(d, this.fontSize, this.fontFamily)), o = e.reduce((d, f) => d + f, 0),
|
|
4490
|
+
const t = this.text.split(""), e = t.map((d) => tt(d, this.fontSize, this.fontFamily)), o = e.reduce((d, f) => d + f, 0), i = this.fontSize / 2;
|
|
4478
4491
|
let a = 1 / 0, n = -1 / 0, h = 1 / 0, l = -1 / 0, c = -o / 2;
|
|
4479
4492
|
t.forEach((d, f) => {
|
|
4480
4493
|
const u = e[f], m = c + u / 2, p = m / (this.transformData.width / 2), y = this.transformData.amplitude * this.fontSize * Math.sin(this.transformData.frequency * Math.PI * p), x = this.transformData.amplitude * this.transformData.frequency * Math.PI * Math.cos(this.transformData.frequency * Math.PI * p);
|
|
4481
4494
|
[
|
|
4482
|
-
{ x: -u / 2, y: -
|
|
4495
|
+
{ x: -u / 2, y: -i },
|
|
4483
4496
|
// top-left
|
|
4484
|
-
{ x: u / 2, y: -
|
|
4497
|
+
{ x: u / 2, y: -i },
|
|
4485
4498
|
// top-right
|
|
4486
|
-
{ x: -u / 2, y:
|
|
4499
|
+
{ x: -u / 2, y: i },
|
|
4487
4500
|
// bottom-left
|
|
4488
|
-
{ x: u / 2, y:
|
|
4501
|
+
{ x: u / 2, y: i }
|
|
4489
4502
|
// bottom-right
|
|
4490
4503
|
].forEach((S) => {
|
|
4491
4504
|
const v = S.x, w = S.y + x * pe * S.x, T = m + v, F = y + w;
|
|
@@ -4500,8 +4513,8 @@ class We extends q {
|
|
|
4500
4513
|
height: l - h
|
|
4501
4514
|
};
|
|
4502
4515
|
}
|
|
4503
|
-
resize(t, e, o,
|
|
4504
|
-
Gt(this, t, e, o,
|
|
4516
|
+
resize(t, e, o, s) {
|
|
4517
|
+
Gt(this, t, e, o, s);
|
|
4505
4518
|
}
|
|
4506
4519
|
getEnabledAnchors() {
|
|
4507
4520
|
return ["top-left", "top-right", "bottom-left", "bottom-right"];
|
|
@@ -4543,7 +4556,7 @@ class ze extends q {
|
|
|
4543
4556
|
};
|
|
4544
4557
|
}
|
|
4545
4558
|
getVisualBoundingBox() {
|
|
4546
|
-
const t = this.text.split(""), e = t.map((f) => tt(f, this.fontSize, this.fontFamily)), o = e.reduce((f, u) => f + u, 0),
|
|
4559
|
+
const t = this.text.split(""), e = t.map((f) => tt(f, this.fontSize, this.fontFamily)), o = e.reduce((f, u) => f + u, 0), s = 0.3, a = this.fontSize / 2;
|
|
4547
4560
|
let n = 1 / 0, h = -1 / 0, l = 1 / 0, c = -1 / 0, g = -o / 2;
|
|
4548
4561
|
t.forEach((f, u) => {
|
|
4549
4562
|
const m = e[u], p = g + m / 2, y = p / (this.transformData.width / 2), x = Math.abs(y), b = this.transformData.amplitude * x, S = b * this.fontSize * Math.sin(this.transformData.frequency * Math.PI * y), v = b * this.transformData.frequency * Math.PI * Math.cos(this.transformData.frequency * Math.PI * y), w = this.transformData.amplitude * Math.sign(y) * Math.sin(this.transformData.frequency * Math.PI * y), T = v + w;
|
|
@@ -4557,7 +4570,7 @@ class ze extends q {
|
|
|
4557
4570
|
{ x: m / 2, y: a }
|
|
4558
4571
|
// bottom-right
|
|
4559
4572
|
].forEach((A) => {
|
|
4560
|
-
const M = A.x, k = A.y + T *
|
|
4573
|
+
const M = A.x, k = A.y + T * s * A.x, I = p + M, O = S + k;
|
|
4561
4574
|
n = Math.min(n, I), h = Math.max(h, I), l = Math.min(l, O), c = Math.max(c, O);
|
|
4562
4575
|
}), g += m;
|
|
4563
4576
|
});
|
|
@@ -4569,22 +4582,22 @@ class ze extends q {
|
|
|
4569
4582
|
height: c - l
|
|
4570
4583
|
};
|
|
4571
4584
|
}
|
|
4572
|
-
resize(t, e, o,
|
|
4573
|
-
const
|
|
4574
|
-
if (
|
|
4575
|
-
const h = e /
|
|
4585
|
+
resize(t, e, o, s) {
|
|
4586
|
+
const i = t.includes("top") || t.includes("bottom"), a = t.includes("middle"), n = s.transformData;
|
|
4587
|
+
if (i) {
|
|
4588
|
+
const h = e / s.width, l = s.fontSize * h;
|
|
4576
4589
|
this.setFontSize(l);
|
|
4577
4590
|
const c = n.width * h;
|
|
4578
4591
|
this.transformData.width = Math.max(50, c);
|
|
4579
4592
|
} else if (a && (t === "middle-left" || t === "middle-right")) {
|
|
4580
|
-
this.fontSize =
|
|
4581
|
-
const h = e -
|
|
4593
|
+
this.fontSize = s.fontSize, this.transformData.width = Math.max(50, e);
|
|
4594
|
+
const h = e - s.width, l = this.rotation * Math.PI / 180, c = Math.cos(l), g = Math.sin(l);
|
|
4582
4595
|
if (t === "middle-left") {
|
|
4583
4596
|
const d = -h / 2;
|
|
4584
|
-
this.x =
|
|
4597
|
+
this.x = s.x + d * c, this.y = s.y + d * g;
|
|
4585
4598
|
} else if (t === "middle-right") {
|
|
4586
4599
|
const d = h / 2;
|
|
4587
|
-
this.x =
|
|
4600
|
+
this.x = s.x + d * c, this.y = s.y + d * g;
|
|
4588
4601
|
}
|
|
4589
4602
|
}
|
|
4590
4603
|
}
|
|
@@ -4638,7 +4651,7 @@ class Xe extends q {
|
|
|
4638
4651
|
};
|
|
4639
4652
|
}
|
|
4640
4653
|
getVisualBoundingBox() {
|
|
4641
|
-
const e = tt(this.text, this.fontSize, this.fontFamily), o = this.fontSize * 1.2,
|
|
4654
|
+
const e = tt(this.text, this.fontSize, this.fontFamily), o = this.fontSize * 1.2, s = -this.transformData.leanAmount * Math.PI / 4, i = Math.tan(s), a = [
|
|
4642
4655
|
{ x: -e / 2, y: -o / 2 },
|
|
4643
4656
|
// top-left
|
|
4644
4657
|
{ x: e / 2, y: -o / 2 },
|
|
@@ -4650,7 +4663,7 @@ class Xe extends q {
|
|
|
4650
4663
|
];
|
|
4651
4664
|
let n = 1 / 0, h = -1 / 0, l = 1 / 0, c = -1 / 0;
|
|
4652
4665
|
a.forEach((d) => {
|
|
4653
|
-
const f = d.x +
|
|
4666
|
+
const f = d.x + i * d.y, u = d.y;
|
|
4654
4667
|
n = Math.min(n, f), h = Math.max(h, f), l = Math.min(l, u), c = Math.max(c, u);
|
|
4655
4668
|
});
|
|
4656
4669
|
const g = 2;
|
|
@@ -4661,22 +4674,22 @@ class Xe extends q {
|
|
|
4661
4674
|
height: c - l
|
|
4662
4675
|
};
|
|
4663
4676
|
}
|
|
4664
|
-
resize(t, e, o,
|
|
4665
|
-
const
|
|
4666
|
-
if (
|
|
4667
|
-
const h = e /
|
|
4677
|
+
resize(t, e, o, s) {
|
|
4678
|
+
const i = t.includes("top") || t.includes("bottom"), a = t.includes("middle"), n = s.transformData;
|
|
4679
|
+
if (i) {
|
|
4680
|
+
const h = e / s.width, l = s.fontSize * h;
|
|
4668
4681
|
this.setFontSize(l);
|
|
4669
4682
|
const c = n.width * h;
|
|
4670
4683
|
this.transformData.width = Math.max(50, c);
|
|
4671
4684
|
} else if (a && (t === "middle-left" || t === "middle-right")) {
|
|
4672
|
-
this.fontSize =
|
|
4685
|
+
this.fontSize = s.fontSize, this.transformData.width = Math.max(50, e);
|
|
4673
4686
|
const h = e - n.width, l = this.rotation * Math.PI / 180, c = Math.cos(l), g = Math.sin(l);
|
|
4674
4687
|
if (t === "middle-left") {
|
|
4675
4688
|
const d = -h / 2;
|
|
4676
|
-
this.x =
|
|
4689
|
+
this.x = s.x + d * c, this.y = s.y + d * g;
|
|
4677
4690
|
} else if (t === "middle-right") {
|
|
4678
4691
|
const d = h / 2;
|
|
4679
|
-
this.x =
|
|
4692
|
+
this.x = s.x + d * c, this.y = s.y + d * g;
|
|
4680
4693
|
}
|
|
4681
4694
|
}
|
|
4682
4695
|
}
|
|
@@ -4719,19 +4732,19 @@ class Ye extends q {
|
|
|
4719
4732
|
};
|
|
4720
4733
|
}
|
|
4721
4734
|
getBoundingBox() {
|
|
4722
|
-
const t = this.transformData.ascendAngle * Math.PI / 180, e = this.transformData.width, o = e * Math.tan(t),
|
|
4735
|
+
const t = this.transformData.ascendAngle * Math.PI / 180, e = this.transformData.width, o = e * Math.tan(t), s = Math.abs(o) + this.fontSize * 1.2, i = o > 0 ? -s : 0;
|
|
4723
4736
|
return {
|
|
4724
4737
|
x: this.x - e / 2,
|
|
4725
|
-
y: this.y +
|
|
4738
|
+
y: this.y + i,
|
|
4726
4739
|
width: e,
|
|
4727
|
-
height:
|
|
4740
|
+
height: s
|
|
4728
4741
|
};
|
|
4729
4742
|
}
|
|
4730
4743
|
getVisualBoundingBox() {
|
|
4731
|
-
const t = this.text.split(""), e = t.map((m) => tt(m, this.fontSize, this.fontFamily)), o = e.reduce((m, p) => m + p, 0),
|
|
4744
|
+
const t = this.text.split(""), e = t.map((m) => tt(m, this.fontSize, this.fontFamily)), o = e.reduce((m, p) => m + p, 0), s = this.transformData.ascendAngle * Math.PI / 180, i = Math.tan(s), a = 1, h = this.fontSize / 2;
|
|
4732
4745
|
let l = 1 / 0, c = -1 / 0, g = 1 / 0, d = -1 / 0, f = -o / 2;
|
|
4733
4746
|
t.forEach((m, p) => {
|
|
4734
|
-
const y = e[p], x = f + y / 2, b = x *
|
|
4747
|
+
const y = e[p], x = f + y / 2, b = x * i;
|
|
4735
4748
|
[
|
|
4736
4749
|
{ x: -y / 2, y: -h },
|
|
4737
4750
|
// top-left
|
|
@@ -4742,7 +4755,7 @@ class Ye extends q {
|
|
|
4742
4755
|
{ x: y / 2, y: h }
|
|
4743
4756
|
// bottom-right
|
|
4744
4757
|
].forEach((v) => {
|
|
4745
|
-
const w = v.x, T = v.y +
|
|
4758
|
+
const w = v.x, T = v.y + i * a * v.x, F = x + w, A = b + T;
|
|
4746
4759
|
l = Math.min(l, F), c = Math.max(c, F), g = Math.min(g, A), d = Math.max(d, A);
|
|
4747
4760
|
}), f += y;
|
|
4748
4761
|
});
|
|
@@ -4754,22 +4767,22 @@ class Ye extends q {
|
|
|
4754
4767
|
height: d - g
|
|
4755
4768
|
};
|
|
4756
4769
|
}
|
|
4757
|
-
resize(t, e, o,
|
|
4758
|
-
const
|
|
4759
|
-
if (
|
|
4760
|
-
const h = e /
|
|
4770
|
+
resize(t, e, o, s) {
|
|
4771
|
+
const i = t.includes("top") || t.includes("bottom"), a = t.includes("middle"), n = s.transformData;
|
|
4772
|
+
if (i) {
|
|
4773
|
+
const h = e / s.width, l = s.fontSize * h;
|
|
4761
4774
|
this.setFontSize(l);
|
|
4762
4775
|
const c = n.width * h;
|
|
4763
4776
|
this.transformData.width = Math.max(50, c);
|
|
4764
4777
|
} else if (a && (t === "middle-left" || t === "middle-right")) {
|
|
4765
|
-
this.fontSize =
|
|
4766
|
-
const h = e -
|
|
4778
|
+
this.fontSize = s.fontSize, this.transformData.width = Math.max(50, e);
|
|
4779
|
+
const h = e - s.width, l = this.rotation * Math.PI / 180, c = Math.cos(l), g = Math.sin(l);
|
|
4767
4780
|
if (t === "middle-left") {
|
|
4768
4781
|
const d = -h / 2;
|
|
4769
|
-
this.x =
|
|
4782
|
+
this.x = s.x + d * c, this.y = s.y + d * g;
|
|
4770
4783
|
} else if (t === "middle-right") {
|
|
4771
4784
|
const d = h / 2;
|
|
4772
|
-
this.x =
|
|
4785
|
+
this.x = s.x + d * c, this.y = s.y + d * g;
|
|
4773
4786
|
}
|
|
4774
4787
|
}
|
|
4775
4788
|
}
|
|
@@ -4803,14 +4816,14 @@ class Ye extends q {
|
|
|
4803
4816
|
}
|
|
4804
4817
|
class Ft extends Q {
|
|
4805
4818
|
constructor(t = {}) {
|
|
4806
|
-
var o,
|
|
4819
|
+
var o, s, i, a, n, h, l, c, g, d, f;
|
|
4807
4820
|
super(t), this.transformType = "shape";
|
|
4808
4821
|
const e = "rectangle";
|
|
4809
4822
|
this.transformData = {
|
|
4810
4823
|
type: "shape",
|
|
4811
4824
|
shapeType: ((o = t.transformData) == null ? void 0 : o.shapeType) || e,
|
|
4812
|
-
width: ((
|
|
4813
|
-
height: ((
|
|
4825
|
+
width: ((s = t.transformData) == null ? void 0 : s.width) || 200,
|
|
4826
|
+
height: ((i = t.transformData) == null ? void 0 : i.height) || 200,
|
|
4814
4827
|
borderRadius: ((a = t.transformData) == null ? void 0 : a.borderRadius) ?? 3,
|
|
4815
4828
|
// Default 3% radius (~6px on 200x200 shape, matches hover border)
|
|
4816
4829
|
radiusX: (n = t.transformData) == null ? void 0 : n.radiusX,
|
|
@@ -4853,34 +4866,34 @@ class Ft extends Q {
|
|
|
4853
4866
|
getVisualBoundingBox() {
|
|
4854
4867
|
const { shapeType: t, width: e, height: o } = this.transformData;
|
|
4855
4868
|
if (t === "circle") {
|
|
4856
|
-
const
|
|
4869
|
+
const s = Math.min(e, o) / 2;
|
|
4857
4870
|
return {
|
|
4858
|
-
x: this.x -
|
|
4859
|
-
y: this.y -
|
|
4860
|
-
width:
|
|
4861
|
-
height:
|
|
4871
|
+
x: this.x - s,
|
|
4872
|
+
y: this.y - s,
|
|
4873
|
+
width: s * 2,
|
|
4874
|
+
height: s * 2
|
|
4862
4875
|
};
|
|
4863
4876
|
}
|
|
4864
4877
|
if (t === "polygon" || t === "star") {
|
|
4865
|
-
const
|
|
4866
|
-
let
|
|
4878
|
+
const s = Math.min(e, o) / 2;
|
|
4879
|
+
let i = 1 / 0, a = 1 / 0, n = -1 / 0, h = -1 / 0;
|
|
4867
4880
|
if (t === "polygon") {
|
|
4868
4881
|
const l = this.transformData.sides || 5;
|
|
4869
4882
|
for (let c = 0; c < l; c++) {
|
|
4870
|
-
const g = c * 2 * Math.PI / l - Math.PI / 2, d =
|
|
4871
|
-
d <
|
|
4883
|
+
const g = c * 2 * Math.PI / l - Math.PI / 2, d = s * Math.cos(g), f = s * Math.sin(g);
|
|
4884
|
+
d < i && (i = d), d > n && (n = d), f < a && (a = f), f > h && (h = f);
|
|
4872
4885
|
}
|
|
4873
4886
|
} else {
|
|
4874
|
-
const l = this.transformData.points || 5, c =
|
|
4887
|
+
const l = this.transformData.points || 5, c = s, g = c * (this.transformData.innerRadius ?? 0.4);
|
|
4875
4888
|
for (let d = 0; d < l * 2; d++) {
|
|
4876
4889
|
const f = d * Math.PI / l - Math.PI / 2, u = d % 2 === 0 ? c : g, m = u * Math.cos(f), p = u * Math.sin(f);
|
|
4877
|
-
m <
|
|
4890
|
+
m < i && (i = m), m > n && (n = m), p < a && (a = p), p > h && (h = p);
|
|
4878
4891
|
}
|
|
4879
4892
|
}
|
|
4880
4893
|
return {
|
|
4881
|
-
x: this.x +
|
|
4894
|
+
x: this.x + i,
|
|
4882
4895
|
y: this.y + a,
|
|
4883
|
-
width: n -
|
|
4896
|
+
width: n - i,
|
|
4884
4897
|
height: h - a
|
|
4885
4898
|
};
|
|
4886
4899
|
}
|
|
@@ -4897,14 +4910,14 @@ class Ft extends Q {
|
|
|
4897
4910
|
*/
|
|
4898
4911
|
render(t, e = !1, o = !1) {
|
|
4899
4912
|
var n;
|
|
4900
|
-
const
|
|
4901
|
-
if (
|
|
4902
|
-
this.renderWithOffscreen(t,
|
|
4913
|
+
const s = this.opacity ?? 1, i = !!((n = this.stroke) != null && n.enabled);
|
|
4914
|
+
if (s < 1 && i) {
|
|
4915
|
+
this.renderWithOffscreen(t, s);
|
|
4903
4916
|
return;
|
|
4904
4917
|
}
|
|
4905
4918
|
t.save(), t.translate(this.x, this.y), t.rotate(D.toRadians(this.rotation)), t.fillStyle = this.transformData.fillColor || "#3b82f6";
|
|
4906
4919
|
const a = this.transformData.fillOpacity ?? 1;
|
|
4907
|
-
t.globalAlpha =
|
|
4920
|
+
t.globalAlpha = s * a, this.renderShape(t), t.restore(), i && this.renderStroke(t, s);
|
|
4908
4921
|
}
|
|
4909
4922
|
/**
|
|
4910
4923
|
* Render fill+stroke to a temporary canvas at full opacity, then composite
|
|
@@ -4912,7 +4925,7 @@ class Ft extends Q {
|
|
|
4912
4925
|
*/
|
|
4913
4926
|
renderWithOffscreen(t, e) {
|
|
4914
4927
|
var f;
|
|
4915
|
-
const { width: o, height:
|
|
4928
|
+
const { width: o, height: s } = this.transformData, a = (((f = this.stroke) == null ? void 0 : f.width) || 2) + 2, n = Math.ceil(o + a * 2), h = Math.ceil(s + a * 2), l = document.createElement("canvas");
|
|
4916
4929
|
l.width = n, l.height = h;
|
|
4917
4930
|
const c = l.getContext("2d");
|
|
4918
4931
|
if (!c) {
|
|
@@ -4936,55 +4949,55 @@ class Ft extends Q {
|
|
|
4936
4949
|
* Trace the shape path without filling or stroking — used by offscreen render
|
|
4937
4950
|
*/
|
|
4938
4951
|
traceShapePath(t) {
|
|
4939
|
-
const { shapeType: e, width: o, height:
|
|
4952
|
+
const { shapeType: e, width: o, height: s } = this.transformData;
|
|
4940
4953
|
switch (e) {
|
|
4941
4954
|
case "rectangle": {
|
|
4942
|
-
const
|
|
4943
|
-
if (
|
|
4944
|
-
const h = Math.min(
|
|
4945
|
-
t.roundRect(a, n, o,
|
|
4955
|
+
const i = this.transformData.borderRadius || 0, a = -o / 2, n = -s / 2;
|
|
4956
|
+
if (i > 0) {
|
|
4957
|
+
const h = Math.min(i / 100 * Math.min(o, s), o / 2, s / 2);
|
|
4958
|
+
t.roundRect(a, n, o, s, h);
|
|
4946
4959
|
} else
|
|
4947
|
-
t.rect(a, n, o,
|
|
4960
|
+
t.rect(a, n, o, s);
|
|
4948
4961
|
break;
|
|
4949
4962
|
}
|
|
4950
4963
|
case "circle": {
|
|
4951
|
-
const
|
|
4952
|
-
t.arc(0, 0,
|
|
4964
|
+
const i = Math.min(o, s) / 2;
|
|
4965
|
+
t.arc(0, 0, i, 0, Math.PI * 2);
|
|
4953
4966
|
break;
|
|
4954
4967
|
}
|
|
4955
4968
|
case "ellipse":
|
|
4956
|
-
t.ellipse(0, 0, o / 2,
|
|
4969
|
+
t.ellipse(0, 0, o / 2, s / 2, 0, 0, Math.PI * 2);
|
|
4957
4970
|
break;
|
|
4958
4971
|
case "triangle": {
|
|
4959
|
-
const
|
|
4960
|
-
t.moveTo(0, -a), t.lineTo(
|
|
4972
|
+
const i = o / 2, a = s / 2;
|
|
4973
|
+
t.moveTo(0, -a), t.lineTo(i, a), t.lineTo(-i, a), t.closePath();
|
|
4961
4974
|
break;
|
|
4962
4975
|
}
|
|
4963
4976
|
case "polygon": {
|
|
4964
|
-
const
|
|
4965
|
-
for (let n = 0; n <
|
|
4966
|
-
const h = n * 2 * Math.PI /
|
|
4977
|
+
const i = this.transformData.sides || 5, a = Math.min(o, s) / 2;
|
|
4978
|
+
for (let n = 0; n < i; n++) {
|
|
4979
|
+
const h = n * 2 * Math.PI / i - Math.PI / 2, l = a * Math.cos(h), c = a * Math.sin(h);
|
|
4967
4980
|
n === 0 ? t.moveTo(l, c) : t.lineTo(l, c);
|
|
4968
4981
|
}
|
|
4969
4982
|
t.closePath();
|
|
4970
4983
|
break;
|
|
4971
4984
|
}
|
|
4972
4985
|
case "star": {
|
|
4973
|
-
const
|
|
4974
|
-
for (let h = 0; h <
|
|
4975
|
-
const l = h * Math.PI /
|
|
4986
|
+
const i = this.transformData.points || 5, a = Math.min(o, s) / 2, n = a * (this.transformData.innerRadius || 0.4);
|
|
4987
|
+
for (let h = 0; h < i * 2; h++) {
|
|
4988
|
+
const l = h * Math.PI / i - Math.PI / 2, c = h % 2 === 0 ? a : n, g = c * Math.cos(l), d = c * Math.sin(l);
|
|
4976
4989
|
h === 0 ? t.moveTo(g, d) : t.lineTo(g, d);
|
|
4977
4990
|
}
|
|
4978
4991
|
t.closePath();
|
|
4979
4992
|
break;
|
|
4980
4993
|
}
|
|
4981
4994
|
case "line": {
|
|
4982
|
-
const
|
|
4983
|
-
t.rect(-
|
|
4995
|
+
const i = o / 2, a = s / 2;
|
|
4996
|
+
t.rect(-i, -a, o, s);
|
|
4984
4997
|
break;
|
|
4985
4998
|
}
|
|
4986
4999
|
default:
|
|
4987
|
-
t.rect(-o / 2, -
|
|
5000
|
+
t.rect(-o / 2, -s / 2, o, s);
|
|
4988
5001
|
}
|
|
4989
5002
|
}
|
|
4990
5003
|
/**
|
|
@@ -4994,32 +5007,32 @@ class Ft extends Q {
|
|
|
4994
5007
|
t.save(), t.translate(this.x, this.y), t.rotate(D.toRadians(this.rotation));
|
|
4995
5008
|
const o = this.stroke;
|
|
4996
5009
|
t.strokeStyle = o.color || "#000000", t.lineWidth = o.width || 2, t.lineCap = o.lineCap || "round", t.lineJoin = o.lineJoin || "round", t.globalAlpha = e * (o.opacity ?? 1), o.dashArray && o.dashArray.length > 0 && t.setLineDash(o.dashArray);
|
|
4997
|
-
const { shapeType:
|
|
4998
|
-
switch (t.beginPath(),
|
|
5010
|
+
const { shapeType: s, width: i, height: a } = this.transformData;
|
|
5011
|
+
switch (t.beginPath(), s) {
|
|
4999
5012
|
case "rectangle": {
|
|
5000
|
-
const n = this.transformData.borderRadius || 0, h = -
|
|
5013
|
+
const n = this.transformData.borderRadius || 0, h = -i / 2, l = -a / 2;
|
|
5001
5014
|
if (n > 0) {
|
|
5002
|
-
const c = Math.min(n / 100 * Math.min(
|
|
5003
|
-
t.roundRect(h, l,
|
|
5015
|
+
const c = Math.min(n / 100 * Math.min(i, a), i / 2, a / 2);
|
|
5016
|
+
t.roundRect(h, l, i, a, c);
|
|
5004
5017
|
} else
|
|
5005
|
-
t.rect(h, l,
|
|
5018
|
+
t.rect(h, l, i, a);
|
|
5006
5019
|
break;
|
|
5007
5020
|
}
|
|
5008
5021
|
case "circle": {
|
|
5009
|
-
const n = Math.min(
|
|
5022
|
+
const n = Math.min(i, a) / 2;
|
|
5010
5023
|
t.arc(0, 0, n, 0, Math.PI * 2);
|
|
5011
5024
|
break;
|
|
5012
5025
|
}
|
|
5013
5026
|
case "ellipse":
|
|
5014
|
-
t.ellipse(0, 0,
|
|
5027
|
+
t.ellipse(0, 0, i / 2, a / 2, 0, 0, Math.PI * 2);
|
|
5015
5028
|
break;
|
|
5016
5029
|
case "triangle": {
|
|
5017
|
-
const n =
|
|
5030
|
+
const n = i / 2, h = a / 2;
|
|
5018
5031
|
t.moveTo(0, -h), t.lineTo(n, h), t.lineTo(-n, h), t.closePath();
|
|
5019
5032
|
break;
|
|
5020
5033
|
}
|
|
5021
5034
|
case "polygon": {
|
|
5022
|
-
const n = this.transformData.sides || 5, h = Math.min(
|
|
5035
|
+
const n = this.transformData.sides || 5, h = Math.min(i, a) / 2;
|
|
5023
5036
|
for (let l = 0; l < n; l++) {
|
|
5024
5037
|
const c = l * 2 * Math.PI / n - Math.PI / 2, g = h * Math.cos(c), d = h * Math.sin(c);
|
|
5025
5038
|
l === 0 ? t.moveTo(g, d) : t.lineTo(g, d);
|
|
@@ -5028,7 +5041,7 @@ class Ft extends Q {
|
|
|
5028
5041
|
break;
|
|
5029
5042
|
}
|
|
5030
5043
|
case "star": {
|
|
5031
|
-
const n = this.transformData.points || 5, h = Math.min(
|
|
5044
|
+
const n = this.transformData.points || 5, h = Math.min(i, a) / 2, l = h * (this.transformData.innerRadius || 0.4);
|
|
5032
5045
|
for (let c = 0; c < n * 2; c++) {
|
|
5033
5046
|
const g = c * Math.PI / n - Math.PI / 2, d = c % 2 === 0 ? h : l, f = d * Math.cos(g), u = d * Math.sin(g);
|
|
5034
5047
|
c === 0 ? t.moveTo(f, u) : t.lineTo(f, u);
|
|
@@ -5037,12 +5050,12 @@ class Ft extends Q {
|
|
|
5037
5050
|
break;
|
|
5038
5051
|
}
|
|
5039
5052
|
case "line": {
|
|
5040
|
-
const n =
|
|
5041
|
-
t.rect(-n, -h,
|
|
5053
|
+
const n = i / 2, h = a / 2;
|
|
5054
|
+
t.rect(-n, -h, i, a);
|
|
5042
5055
|
break;
|
|
5043
5056
|
}
|
|
5044
5057
|
default:
|
|
5045
|
-
t.rect(-
|
|
5058
|
+
t.rect(-i / 2, -a / 2, i, a);
|
|
5046
5059
|
}
|
|
5047
5060
|
t.stroke(), t.restore();
|
|
5048
5061
|
}
|
|
@@ -5050,32 +5063,32 @@ class Ft extends Q {
|
|
|
5050
5063
|
* Render the specific shape based on shapeType
|
|
5051
5064
|
*/
|
|
5052
5065
|
renderShape(t) {
|
|
5053
|
-
const { shapeType: e, width: o, height:
|
|
5066
|
+
const { shapeType: e, width: o, height: s } = this.transformData;
|
|
5054
5067
|
switch (t.beginPath(), e) {
|
|
5055
5068
|
case "rectangle":
|
|
5056
|
-
this.renderRectangle(t, o,
|
|
5069
|
+
this.renderRectangle(t, o, s);
|
|
5057
5070
|
break;
|
|
5058
5071
|
case "circle":
|
|
5059
|
-
this.renderCircle(t, Math.min(o,
|
|
5072
|
+
this.renderCircle(t, Math.min(o, s) / 2);
|
|
5060
5073
|
break;
|
|
5061
5074
|
case "ellipse":
|
|
5062
|
-
this.renderEllipse(t, o / 2,
|
|
5075
|
+
this.renderEllipse(t, o / 2, s / 2);
|
|
5063
5076
|
break;
|
|
5064
5077
|
case "triangle":
|
|
5065
|
-
this.renderTriangle(t, o,
|
|
5078
|
+
this.renderTriangle(t, o, s);
|
|
5066
5079
|
break;
|
|
5067
5080
|
case "polygon":
|
|
5068
|
-
this.renderPolygon(t, Math.min(o,
|
|
5081
|
+
this.renderPolygon(t, Math.min(o, s) / 2);
|
|
5069
5082
|
break;
|
|
5070
5083
|
case "star":
|
|
5071
|
-
this.renderStar(t, Math.min(o,
|
|
5084
|
+
this.renderStar(t, Math.min(o, s) / 2);
|
|
5072
5085
|
break;
|
|
5073
5086
|
case "line":
|
|
5074
|
-
this.renderLine(t, o,
|
|
5087
|
+
this.renderLine(t, o, s);
|
|
5075
5088
|
return;
|
|
5076
5089
|
// Line uses stroke, not fill
|
|
5077
5090
|
default:
|
|
5078
|
-
this.renderRectangle(t, o,
|
|
5091
|
+
this.renderRectangle(t, o, s);
|
|
5079
5092
|
}
|
|
5080
5093
|
t.fill();
|
|
5081
5094
|
}
|
|
@@ -5083,12 +5096,12 @@ class Ft extends Q {
|
|
|
5083
5096
|
* Render a rectangle (with optional border radius)
|
|
5084
5097
|
*/
|
|
5085
5098
|
renderRectangle(t, e, o) {
|
|
5086
|
-
const
|
|
5087
|
-
if (
|
|
5088
|
-
const n = Math.min(
|
|
5089
|
-
t.roundRect(
|
|
5099
|
+
const s = this.transformData.borderRadius || 0, i = -e / 2, a = -o / 2;
|
|
5100
|
+
if (s > 0) {
|
|
5101
|
+
const n = Math.min(s / 100 * Math.min(e, o), e / 2, o / 2);
|
|
5102
|
+
t.roundRect(i, a, e, o, n);
|
|
5090
5103
|
} else
|
|
5091
|
-
t.rect(
|
|
5104
|
+
t.rect(i, a, e, o);
|
|
5092
5105
|
}
|
|
5093
5106
|
/**
|
|
5094
5107
|
* Render a circle
|
|
@@ -5106,16 +5119,16 @@ class Ft extends Q {
|
|
|
5106
5119
|
* Render a triangle (isosceles, pointing up)
|
|
5107
5120
|
*/
|
|
5108
5121
|
renderTriangle(t, e, o) {
|
|
5109
|
-
const
|
|
5110
|
-
t.moveTo(0, -
|
|
5122
|
+
const s = e / 2, i = o / 2;
|
|
5123
|
+
t.moveTo(0, -i), t.lineTo(s, i), t.lineTo(-s, i), t.closePath();
|
|
5111
5124
|
}
|
|
5112
5125
|
/**
|
|
5113
5126
|
* Render a regular polygon
|
|
5114
5127
|
*/
|
|
5115
5128
|
renderPolygon(t, e) {
|
|
5116
|
-
const o = Math.max(3, Math.min(20, this.transformData.sides || 5)),
|
|
5129
|
+
const o = Math.max(3, Math.min(20, this.transformData.sides || 5)), s = Math.PI * 2 / o, i = -Math.PI / 2;
|
|
5117
5130
|
for (let a = 0; a <= o; a++) {
|
|
5118
|
-
const n =
|
|
5131
|
+
const n = i + s * a, h = Math.cos(n) * e, l = Math.sin(n) * e;
|
|
5119
5132
|
a === 0 ? t.moveTo(h, l) : t.lineTo(h, l);
|
|
5120
5133
|
}
|
|
5121
5134
|
t.closePath();
|
|
@@ -5124,9 +5137,9 @@ class Ft extends Q {
|
|
|
5124
5137
|
* Render a star
|
|
5125
5138
|
*/
|
|
5126
5139
|
renderStar(t, e) {
|
|
5127
|
-
const o = Math.max(3, Math.min(20, this.transformData.points || 5)),
|
|
5140
|
+
const o = Math.max(3, Math.min(20, this.transformData.points || 5)), s = Math.max(0.1, Math.min(0.9, this.transformData.innerRadius || 0.4)), i = e * s, a = Math.PI / o, n = -Math.PI / 2;
|
|
5128
5141
|
for (let h = 0; h < o * 2; h++) {
|
|
5129
|
-
const l = n + a * h, c = h % 2 === 0 ? e :
|
|
5142
|
+
const l = n + a * h, c = h % 2 === 0 ? e : i, g = Math.cos(l) * c, d = Math.sin(l) * c;
|
|
5130
5143
|
h === 0 ? t.moveTo(g, d) : t.lineTo(g, d);
|
|
5131
5144
|
}
|
|
5132
5145
|
t.closePath();
|
|
@@ -5135,20 +5148,20 @@ class Ft extends Q {
|
|
|
5135
5148
|
* Render a line
|
|
5136
5149
|
*/
|
|
5137
5150
|
renderLine(t, e, o) {
|
|
5138
|
-
const
|
|
5139
|
-
t.moveTo(-
|
|
5151
|
+
const s = e / 2, i = o;
|
|
5152
|
+
t.moveTo(-s, 0), t.lineTo(s, 0), t.strokeStyle = this.transformData.fillColor || "#3b82f6", t.lineWidth = i, t.lineCap = "round", t.stroke();
|
|
5140
5153
|
}
|
|
5141
5154
|
/**
|
|
5142
5155
|
* Handle resize - maintain aspect ratio for circles, free resize for others
|
|
5143
5156
|
*/
|
|
5144
|
-
resize(t, e, o,
|
|
5145
|
-
const { shapeType:
|
|
5146
|
-
if (
|
|
5147
|
-
const c = Math.max(e /
|
|
5148
|
-
this.transformData.width =
|
|
5149
|
-
} else
|
|
5150
|
-
this.rotation =
|
|
5151
|
-
const a = this.getFixedCorner(t,
|
|
5157
|
+
resize(t, e, o, s) {
|
|
5158
|
+
const { shapeType: i } = this.transformData;
|
|
5159
|
+
if (i === "circle" || i === "polygon" || i === "star") {
|
|
5160
|
+
const c = Math.max(e / s.transformData.width, o / s.transformData.height);
|
|
5161
|
+
this.transformData.width = s.transformData.width * c, this.transformData.height = s.transformData.height * c;
|
|
5162
|
+
} else i === "line" ? (this.transformData.width = e, this.transformData.height = s.transformData.height) : (this.transformData.width = e, this.transformData.height = o);
|
|
5163
|
+
this.rotation = s.rotation;
|
|
5164
|
+
const a = this.getFixedCorner(t, s), n = this.getOppositeAnchor(t), h = this.getBoundingBox(), l = this.getCornerOffset(n, h);
|
|
5152
5165
|
return this.x = a.x - l.x, this.y = a.y - l.y, !0;
|
|
5153
5166
|
}
|
|
5154
5167
|
/**
|
|
@@ -5180,71 +5193,71 @@ class Ft extends Q {
|
|
|
5180
5193
|
width: e.transformData.width,
|
|
5181
5194
|
height: e.transformData.height
|
|
5182
5195
|
};
|
|
5183
|
-
let
|
|
5196
|
+
let s, i;
|
|
5184
5197
|
switch (t) {
|
|
5185
5198
|
case "top-left":
|
|
5186
|
-
|
|
5199
|
+
s = o.x + o.width, i = o.y + o.height;
|
|
5187
5200
|
break;
|
|
5188
5201
|
case "top-right":
|
|
5189
|
-
|
|
5202
|
+
s = o.x, i = o.y + o.height;
|
|
5190
5203
|
break;
|
|
5191
5204
|
case "bottom-left":
|
|
5192
|
-
|
|
5205
|
+
s = o.x + o.width, i = o.y;
|
|
5193
5206
|
break;
|
|
5194
5207
|
case "bottom-right":
|
|
5195
|
-
|
|
5208
|
+
s = o.x, i = o.y;
|
|
5196
5209
|
break;
|
|
5197
5210
|
case "middle-left":
|
|
5198
|
-
|
|
5211
|
+
s = o.x + o.width, i = o.y + o.height / 2;
|
|
5199
5212
|
break;
|
|
5200
5213
|
case "middle-right":
|
|
5201
|
-
|
|
5214
|
+
s = o.x, i = o.y + o.height / 2;
|
|
5202
5215
|
break;
|
|
5203
5216
|
case "middle-top":
|
|
5204
|
-
|
|
5217
|
+
s = o.x + o.width / 2, i = o.y + o.height;
|
|
5205
5218
|
break;
|
|
5206
5219
|
case "middle-bottom":
|
|
5207
|
-
|
|
5220
|
+
s = o.x + o.width / 2, i = o.y;
|
|
5208
5221
|
break;
|
|
5209
5222
|
default:
|
|
5210
|
-
|
|
5223
|
+
s = o.x + o.width / 2, i = o.y + o.height / 2;
|
|
5211
5224
|
}
|
|
5212
|
-
return { x:
|
|
5225
|
+
return { x: s, y: i };
|
|
5213
5226
|
}
|
|
5214
5227
|
/**
|
|
5215
5228
|
* Get the offset of a corner from the center
|
|
5216
5229
|
*/
|
|
5217
5230
|
getCornerOffset(t, e) {
|
|
5218
|
-
let o,
|
|
5231
|
+
let o, s;
|
|
5219
5232
|
switch (t) {
|
|
5220
5233
|
case "top-left":
|
|
5221
|
-
o = -e.width / 2,
|
|
5234
|
+
o = -e.width / 2, s = -e.height / 2;
|
|
5222
5235
|
break;
|
|
5223
5236
|
case "top-right":
|
|
5224
|
-
o = e.width / 2,
|
|
5237
|
+
o = e.width / 2, s = -e.height / 2;
|
|
5225
5238
|
break;
|
|
5226
5239
|
case "bottom-left":
|
|
5227
|
-
o = -e.width / 2,
|
|
5240
|
+
o = -e.width / 2, s = e.height / 2;
|
|
5228
5241
|
break;
|
|
5229
5242
|
case "bottom-right":
|
|
5230
|
-
o = e.width / 2,
|
|
5243
|
+
o = e.width / 2, s = e.height / 2;
|
|
5231
5244
|
break;
|
|
5232
5245
|
case "middle-left":
|
|
5233
|
-
o = -e.width / 2,
|
|
5246
|
+
o = -e.width / 2, s = 0;
|
|
5234
5247
|
break;
|
|
5235
5248
|
case "middle-right":
|
|
5236
|
-
o = e.width / 2,
|
|
5249
|
+
o = e.width / 2, s = 0;
|
|
5237
5250
|
break;
|
|
5238
5251
|
case "middle-top":
|
|
5239
|
-
o = 0,
|
|
5252
|
+
o = 0, s = -e.height / 2;
|
|
5240
5253
|
break;
|
|
5241
5254
|
case "middle-bottom":
|
|
5242
|
-
o = 0,
|
|
5255
|
+
o = 0, s = e.height / 2;
|
|
5243
5256
|
break;
|
|
5244
5257
|
default:
|
|
5245
|
-
o = 0,
|
|
5258
|
+
o = 0, s = 0;
|
|
5246
5259
|
}
|
|
5247
|
-
return { x: o, y:
|
|
5260
|
+
return { x: o, y: s };
|
|
5248
5261
|
}
|
|
5249
5262
|
/**
|
|
5250
5263
|
* Get enabled anchors - all 8 anchors for most shapes, only corners for circles/polygons
|
|
@@ -5290,13 +5303,13 @@ class Ft extends Q {
|
|
|
5290
5303
|
}
|
|
5291
5304
|
class Mt extends Q {
|
|
5292
5305
|
constructor(t = {}) {
|
|
5293
|
-
var e, o,
|
|
5306
|
+
var e, o, s, i, a, n, h, l, c, g;
|
|
5294
5307
|
super(t), this.transformType = "path", this.transformData = {
|
|
5295
5308
|
type: "path",
|
|
5296
5309
|
points: ((e = t.transformData) == null ? void 0 : e.points) || [],
|
|
5297
5310
|
closed: ((o = t.transformData) == null ? void 0 : o.closed) ?? !1,
|
|
5298
|
-
width: ((
|
|
5299
|
-
height: ((
|
|
5311
|
+
width: ((s = t.transformData) == null ? void 0 : s.width) || 200,
|
|
5312
|
+
height: ((i = t.transformData) == null ? void 0 : i.height) || 200,
|
|
5300
5313
|
fillEnabled: ((a = t.transformData) == null ? void 0 : a.fillEnabled) ?? !1,
|
|
5301
5314
|
fillColor: ((n = t.transformData) == null ? void 0 : n.fillColor) || zt(),
|
|
5302
5315
|
fillOpacity: ((h = t.transformData) == null ? void 0 : h.fillOpacity) ?? 1,
|
|
@@ -5344,11 +5357,11 @@ class Mt extends Q {
|
|
|
5344
5357
|
* @param p3 End point
|
|
5345
5358
|
* @param t Parameter from 0 to 1
|
|
5346
5359
|
*/
|
|
5347
|
-
bezierPoint(t, e, o,
|
|
5348
|
-
const a = 1 -
|
|
5360
|
+
bezierPoint(t, e, o, s, i) {
|
|
5361
|
+
const a = 1 - i, n = a * a, h = n * a, l = i * i, c = l * i;
|
|
5349
5362
|
return {
|
|
5350
|
-
x: h * t.x + 3 * n *
|
|
5351
|
-
y: h * t.y + 3 * n *
|
|
5363
|
+
x: h * t.x + 3 * n * i * e.x + 3 * a * l * o.x + c * s.x,
|
|
5364
|
+
y: h * t.y + 3 * n * i * e.y + 3 * a * l * o.y + c * s.y
|
|
5352
5365
|
};
|
|
5353
5366
|
}
|
|
5354
5367
|
/**
|
|
@@ -5360,14 +5373,14 @@ class Mt extends Q {
|
|
|
5360
5373
|
const { points: t } = this.transformData;
|
|
5361
5374
|
if (t.length === 0)
|
|
5362
5375
|
return { x: 0, y: 0, width: 0, height: 0 };
|
|
5363
|
-
let e = 1 / 0, o = 1 / 0,
|
|
5376
|
+
let e = 1 / 0, o = 1 / 0, s = -1 / 0, i = -1 / 0;
|
|
5364
5377
|
for (let d = 0; d < t.length; d++) {
|
|
5365
5378
|
const f = t[d], u = t[(d + 1) % t.length];
|
|
5366
5379
|
if (d === t.length - 1 && !this.transformData.closed) {
|
|
5367
|
-
e = Math.min(e, f.x), o = Math.min(o, f.y),
|
|
5380
|
+
e = Math.min(e, f.x), o = Math.min(o, f.y), s = Math.max(s, f.x), i = Math.max(i, f.y);
|
|
5368
5381
|
break;
|
|
5369
5382
|
}
|
|
5370
|
-
if (e = Math.min(e, f.x), o = Math.min(o, f.y),
|
|
5383
|
+
if (e = Math.min(e, f.x), o = Math.min(o, f.y), s = Math.max(s, f.x), i = Math.max(i, f.y), f.handleOut || u.handleIn) {
|
|
5371
5384
|
const p = { x: f.x, y: f.y }, y = {
|
|
5372
5385
|
x: f.x + (((h = f.handleOut) == null ? void 0 : h.x) || 0),
|
|
5373
5386
|
y: f.y + (((l = f.handleOut) == null ? void 0 : l.y) || 0)
|
|
@@ -5377,7 +5390,7 @@ class Mt extends Q {
|
|
|
5377
5390
|
}, b = { x: u.x, y: u.y }, S = 20;
|
|
5378
5391
|
for (let v = 0; v <= S; v++) {
|
|
5379
5392
|
const w = v / S, T = this.bezierPoint(p, y, x, b, w);
|
|
5380
|
-
e = Math.min(e, T.x), o = Math.min(o, T.y),
|
|
5393
|
+
e = Math.min(e, T.x), o = Math.min(o, T.y), s = Math.max(s, T.x), i = Math.max(i, T.y);
|
|
5381
5394
|
}
|
|
5382
5395
|
}
|
|
5383
5396
|
}
|
|
@@ -5385,8 +5398,8 @@ class Mt extends Q {
|
|
|
5385
5398
|
return {
|
|
5386
5399
|
x: e - n,
|
|
5387
5400
|
y: o - n,
|
|
5388
|
-
width:
|
|
5389
|
-
height:
|
|
5401
|
+
width: s - e + a,
|
|
5402
|
+
height: i - o + a
|
|
5390
5403
|
};
|
|
5391
5404
|
}
|
|
5392
5405
|
/**
|
|
@@ -5400,28 +5413,28 @@ class Mt extends Q {
|
|
|
5400
5413
|
* Render the path
|
|
5401
5414
|
*/
|
|
5402
5415
|
render(t, e = !1, o = !1) {
|
|
5403
|
-
const { points:
|
|
5404
|
-
if (
|
|
5416
|
+
const { points: s, closed: i, fillEnabled: a, fillColor: n, fillOpacity: h, strokeEnabled: l, strokeColor: c, strokeWidth: g } = this.transformData;
|
|
5417
|
+
if (s.length === 0)
|
|
5405
5418
|
return;
|
|
5406
5419
|
t.save(), t.translate(this.x, this.y), t.rotate(D.toRadians(this.rotation));
|
|
5407
5420
|
const d = this.calculatePathBounds(), f = d.x + d.width / 2, u = d.y + d.height / 2;
|
|
5408
|
-
t.translate(-f, -u), t.beginPath(), this.renderPath(t), a &&
|
|
5421
|
+
t.translate(-f, -u), t.beginPath(), this.renderPath(t), a && i && n && (t.fillStyle = n, t.globalAlpha = h ?? 1, t.fill()), l && c && g && (t.strokeStyle = c, t.lineWidth = g, t.lineCap = "round", t.lineJoin = "round", t.globalAlpha = 1, t.stroke()), t.restore();
|
|
5409
5422
|
}
|
|
5410
5423
|
/**
|
|
5411
5424
|
* Render the path using Canvas API bezier curves
|
|
5412
5425
|
*/
|
|
5413
5426
|
renderPath(t) {
|
|
5414
|
-
var
|
|
5427
|
+
var i, a, n, h;
|
|
5415
5428
|
const { points: e, closed: o } = this.transformData;
|
|
5416
5429
|
if (e.length === 0) return;
|
|
5417
|
-
const
|
|
5418
|
-
t.moveTo(
|
|
5430
|
+
const s = e[0];
|
|
5431
|
+
t.moveTo(s.x, s.y);
|
|
5419
5432
|
for (let l = 0; l < e.length; l++) {
|
|
5420
5433
|
const c = e[l], g = e[(l + 1) % e.length];
|
|
5421
5434
|
if (l === e.length - 1 && !o)
|
|
5422
5435
|
break;
|
|
5423
5436
|
if (c.handleOut || g.handleIn) {
|
|
5424
|
-
const f = c.x + (((
|
|
5437
|
+
const f = c.x + (((i = c.handleOut) == null ? void 0 : i.x) || 0), u = c.y + (((a = c.handleOut) == null ? void 0 : a.y) || 0), m = g.x + (((n = g.handleIn) == null ? void 0 : n.x) || 0), p = g.y + (((h = g.handleIn) == null ? void 0 : h.y) || 0);
|
|
5425
5438
|
t.bezierCurveTo(f, u, m, p, g.x, g.y);
|
|
5426
5439
|
} else
|
|
5427
5440
|
t.lineTo(g.x, g.y);
|
|
@@ -5431,11 +5444,11 @@ class Mt extends Q {
|
|
|
5431
5444
|
/**
|
|
5432
5445
|
* Handle resize - scale all points relative to center
|
|
5433
5446
|
*/
|
|
5434
|
-
resize(t, e, o,
|
|
5435
|
-
const
|
|
5436
|
-
if (
|
|
5447
|
+
resize(t, e, o, s) {
|
|
5448
|
+
const i = s.transformData.width, a = s.transformData.height;
|
|
5449
|
+
if (i === 0 || a === 0)
|
|
5437
5450
|
return !1;
|
|
5438
|
-
const n = e /
|
|
5451
|
+
const n = e / i, h = o / a, l = s.transformData.points;
|
|
5439
5452
|
let c = 1 / 0, g = 1 / 0, d = -1 / 0, f = -1 / 0;
|
|
5440
5453
|
for (const S of l)
|
|
5441
5454
|
c = Math.min(c, S.x), g = Math.min(g, S.y), d = Math.max(d, S.x), f = Math.max(f, S.y);
|
|
@@ -5446,8 +5459,8 @@ class Mt extends Q {
|
|
|
5446
5459
|
y: m + (S.y - m) * h,
|
|
5447
5460
|
handleIn: S.handleIn ? { x: S.handleIn.x * n, y: S.handleIn.y * h } : void 0,
|
|
5448
5461
|
handleOut: S.handleOut ? { x: S.handleOut.x * n, y: S.handleOut.y * h } : void 0
|
|
5449
|
-
})), this.transformData.width = e, this.transformData.height = o, this.rotation =
|
|
5450
|
-
const p = this.getFixedCorner(t,
|
|
5462
|
+
})), this.transformData.width = e, this.transformData.height = o, this.rotation = s.rotation;
|
|
5463
|
+
const p = this.getFixedCorner(t, s), y = this.getOppositeAnchor(t), x = this.getBoundingBox(), b = this.getCornerOffset(y, x);
|
|
5451
5464
|
return this.x = p.x - b.x, this.y = p.y - b.y, !0;
|
|
5452
5465
|
}
|
|
5453
5466
|
/**
|
|
@@ -5479,71 +5492,71 @@ class Mt extends Q {
|
|
|
5479
5492
|
width: e.transformData.width,
|
|
5480
5493
|
height: e.transformData.height
|
|
5481
5494
|
};
|
|
5482
|
-
let
|
|
5495
|
+
let s, i;
|
|
5483
5496
|
switch (t) {
|
|
5484
5497
|
case "top-left":
|
|
5485
|
-
|
|
5498
|
+
s = o.x + o.width, i = o.y + o.height;
|
|
5486
5499
|
break;
|
|
5487
5500
|
case "top-right":
|
|
5488
|
-
|
|
5501
|
+
s = o.x, i = o.y + o.height;
|
|
5489
5502
|
break;
|
|
5490
5503
|
case "bottom-left":
|
|
5491
|
-
|
|
5504
|
+
s = o.x + o.width, i = o.y;
|
|
5492
5505
|
break;
|
|
5493
5506
|
case "bottom-right":
|
|
5494
|
-
|
|
5507
|
+
s = o.x, i = o.y;
|
|
5495
5508
|
break;
|
|
5496
5509
|
case "middle-left":
|
|
5497
|
-
|
|
5510
|
+
s = o.x + o.width, i = o.y + o.height / 2;
|
|
5498
5511
|
break;
|
|
5499
5512
|
case "middle-right":
|
|
5500
|
-
|
|
5513
|
+
s = o.x, i = o.y + o.height / 2;
|
|
5501
5514
|
break;
|
|
5502
5515
|
case "middle-top":
|
|
5503
|
-
|
|
5516
|
+
s = o.x + o.width / 2, i = o.y + o.height;
|
|
5504
5517
|
break;
|
|
5505
5518
|
case "middle-bottom":
|
|
5506
|
-
|
|
5519
|
+
s = o.x + o.width / 2, i = o.y;
|
|
5507
5520
|
break;
|
|
5508
5521
|
default:
|
|
5509
|
-
|
|
5522
|
+
s = o.x + o.width / 2, i = o.y + o.height / 2;
|
|
5510
5523
|
}
|
|
5511
|
-
return { x:
|
|
5524
|
+
return { x: s, y: i };
|
|
5512
5525
|
}
|
|
5513
5526
|
/**
|
|
5514
5527
|
* Get the offset of a corner from the center
|
|
5515
5528
|
*/
|
|
5516
5529
|
getCornerOffset(t, e) {
|
|
5517
|
-
let o,
|
|
5530
|
+
let o, s;
|
|
5518
5531
|
switch (t) {
|
|
5519
5532
|
case "top-left":
|
|
5520
|
-
o = -e.width / 2,
|
|
5533
|
+
o = -e.width / 2, s = -e.height / 2;
|
|
5521
5534
|
break;
|
|
5522
5535
|
case "top-right":
|
|
5523
|
-
o = e.width / 2,
|
|
5536
|
+
o = e.width / 2, s = -e.height / 2;
|
|
5524
5537
|
break;
|
|
5525
5538
|
case "bottom-left":
|
|
5526
|
-
o = -e.width / 2,
|
|
5539
|
+
o = -e.width / 2, s = e.height / 2;
|
|
5527
5540
|
break;
|
|
5528
5541
|
case "bottom-right":
|
|
5529
|
-
o = e.width / 2,
|
|
5542
|
+
o = e.width / 2, s = e.height / 2;
|
|
5530
5543
|
break;
|
|
5531
5544
|
case "middle-left":
|
|
5532
|
-
o = -e.width / 2,
|
|
5545
|
+
o = -e.width / 2, s = 0;
|
|
5533
5546
|
break;
|
|
5534
5547
|
case "middle-right":
|
|
5535
|
-
o = e.width / 2,
|
|
5548
|
+
o = e.width / 2, s = 0;
|
|
5536
5549
|
break;
|
|
5537
5550
|
case "middle-top":
|
|
5538
|
-
o = 0,
|
|
5551
|
+
o = 0, s = -e.height / 2;
|
|
5539
5552
|
break;
|
|
5540
5553
|
case "middle-bottom":
|
|
5541
|
-
o = 0,
|
|
5554
|
+
o = 0, s = e.height / 2;
|
|
5542
5555
|
break;
|
|
5543
5556
|
default:
|
|
5544
|
-
o = 0,
|
|
5557
|
+
o = 0, s = 0;
|
|
5545
5558
|
}
|
|
5546
|
-
return { x: o, y:
|
|
5559
|
+
return { x: o, y: s };
|
|
5547
5560
|
}
|
|
5548
5561
|
/**
|
|
5549
5562
|
* Get enabled anchors - all 8 anchors for free resize
|
|
@@ -5618,7 +5631,7 @@ const _e = {
|
|
|
5618
5631
|
{
|
|
5619
5632
|
key: "amplitude",
|
|
5620
5633
|
label: "Wave Amplitude",
|
|
5621
|
-
defaultInternalValue:
|
|
5634
|
+
defaultInternalValue: it.amplitude,
|
|
5622
5635
|
// Slider 0-100 maps to internal -0.5 to 0.5 (-50% to +50%)
|
|
5623
5636
|
toSlider: (r) => (r + 0.5) * 100,
|
|
5624
5637
|
fromSlider: (r) => r / 100 - 0.5,
|
|
@@ -5627,7 +5640,7 @@ const _e = {
|
|
|
5627
5640
|
{
|
|
5628
5641
|
key: "frequency",
|
|
5629
5642
|
label: "Wave Frequency",
|
|
5630
|
-
defaultInternalValue:
|
|
5643
|
+
defaultInternalValue: it.frequency,
|
|
5631
5644
|
step: 5,
|
|
5632
5645
|
// 5% steps for smoother control
|
|
5633
5646
|
// Slider 0-100 maps to internal 1 to 5
|
|
@@ -5821,17 +5834,17 @@ class ut extends Q {
|
|
|
5821
5834
|
getBoundingBox() {
|
|
5822
5835
|
if (this.children.length === 0)
|
|
5823
5836
|
return { x: this.x - 50, y: this.y - 50, width: 100, height: 100 };
|
|
5824
|
-
let t = 1 / 0, e = 1 / 0, o = -1 / 0,
|
|
5825
|
-
return this.children.forEach((
|
|
5826
|
-
const a =
|
|
5827
|
-
this._getRotatedCorners(
|
|
5828
|
-
t = Math.min(t, h.x), e = Math.min(e, h.y), o = Math.max(o, h.x),
|
|
5837
|
+
let t = 1 / 0, e = 1 / 0, o = -1 / 0, s = -1 / 0;
|
|
5838
|
+
return this.children.forEach((i) => {
|
|
5839
|
+
const a = i.getVisualBoundingBox();
|
|
5840
|
+
this._getRotatedCorners(i, a).forEach((h) => {
|
|
5841
|
+
t = Math.min(t, h.x), e = Math.min(e, h.y), o = Math.max(o, h.x), s = Math.max(s, h.y);
|
|
5829
5842
|
});
|
|
5830
5843
|
}), {
|
|
5831
5844
|
x: t,
|
|
5832
5845
|
y: e,
|
|
5833
5846
|
width: o - t,
|
|
5834
|
-
height:
|
|
5847
|
+
height: s - e
|
|
5835
5848
|
};
|
|
5836
5849
|
}
|
|
5837
5850
|
/**
|
|
@@ -5855,7 +5868,7 @@ class ut extends Q {
|
|
|
5855
5868
|
* Get the four corners of an element's bounding box in world space
|
|
5856
5869
|
*/
|
|
5857
5870
|
_getRotatedCorners(t, e) {
|
|
5858
|
-
const o = new R(t),
|
|
5871
|
+
const o = new R(t), s = e.x + e.width / 2, i = e.y + e.height / 2, a = s - t.x, n = i - t.y;
|
|
5859
5872
|
return [
|
|
5860
5873
|
{ localX: a - e.width / 2, localY: n - e.height / 2 },
|
|
5861
5874
|
{ localX: a + e.width / 2, localY: n - e.height / 2 },
|
|
@@ -5895,8 +5908,8 @@ class ut extends Q {
|
|
|
5895
5908
|
* Elements with isClipping=true clip all elements below them in the group
|
|
5896
5909
|
*/
|
|
5897
5910
|
render(t, e = !1, o = !1) {
|
|
5898
|
-
const
|
|
5899
|
-
|
|
5911
|
+
const s = this.children.filter((a) => a.visible !== !1);
|
|
5912
|
+
s.some((a) => a.isClipping) ? Te()(t, s) : s.forEach((a) => {
|
|
5900
5913
|
a.render(t, !1);
|
|
5901
5914
|
}), e ? this._renderGroupOutline(t, 1) : o && this._renderGroupOutline(t, 0.3);
|
|
5902
5915
|
}
|
|
@@ -5907,8 +5920,8 @@ class ut extends Q {
|
|
|
5907
5920
|
_renderGroupOutline(t, e = 1) {
|
|
5908
5921
|
const o = this.getOrientedBoundingBox();
|
|
5909
5922
|
t.save(), t.globalAlpha = e, t.strokeStyle = Wt(), t.lineWidth = 2, t.setLineDash([5, 5]);
|
|
5910
|
-
const
|
|
5911
|
-
this.rotation !== 0 && (t.translate(
|
|
5923
|
+
const s = this._rotationCenterX || this.x, i = this._rotationCenterY || this.y;
|
|
5924
|
+
this.rotation !== 0 && (t.translate(s, i), t.rotate(-this.rotation * Math.PI / 180), t.translate(-s, -i)), t.strokeRect(o.x, o.y, o.width, o.height), t.setLineDash([]), t.restore();
|
|
5912
5925
|
}
|
|
5913
5926
|
/**
|
|
5914
5927
|
* Get oriented bounding box (uses cached base dimensions for stability during rotation)
|
|
@@ -5925,13 +5938,13 @@ class ut extends Q {
|
|
|
5925
5938
|
if (this._baseBBoxWidth > 0 && this._baseBBoxHeight > 0)
|
|
5926
5939
|
t = this._baseBBoxWidth, e = this._baseBBoxHeight;
|
|
5927
5940
|
else {
|
|
5928
|
-
const
|
|
5929
|
-
t =
|
|
5941
|
+
const i = this.getBoundingBox();
|
|
5942
|
+
t = i.width, e = i.height, this._baseBBoxWidth = t, this._baseBBoxHeight = e;
|
|
5930
5943
|
}
|
|
5931
|
-
const o = this._rotationCenterX || this.x,
|
|
5944
|
+
const o = this._rotationCenterX || this.x, s = this._rotationCenterY || this.y;
|
|
5932
5945
|
return {
|
|
5933
5946
|
x: o - t / 2,
|
|
5934
|
-
y:
|
|
5947
|
+
y: s - e / 2,
|
|
5935
5948
|
width: t,
|
|
5936
5949
|
height: e
|
|
5937
5950
|
};
|
|
@@ -5950,40 +5963,40 @@ class ut extends Q {
|
|
|
5950
5963
|
setRotation(t) {
|
|
5951
5964
|
const e = t - this.rotation;
|
|
5952
5965
|
this.rotation = t;
|
|
5953
|
-
const o = this._rotationCenterX || this.x,
|
|
5954
|
-
this.children.forEach((
|
|
5955
|
-
const a = R.rotatePointAroundAnchor(
|
|
5956
|
-
|
|
5957
|
-
}), this.x = o, this.y =
|
|
5966
|
+
const o = this._rotationCenterX || this.x, s = this._rotationCenterY || this.y;
|
|
5967
|
+
this.children.forEach((i) => {
|
|
5968
|
+
const a = R.rotatePointAroundAnchor(i.x, i.y, o, s, e);
|
|
5969
|
+
i.x = a.x, i.y = a.y, i.setRotation(i.rotation + e);
|
|
5970
|
+
}), this.x = o, this.y = s;
|
|
5958
5971
|
}
|
|
5959
5972
|
/**
|
|
5960
5973
|
* Resize the group (scales all children proportionally)
|
|
5961
5974
|
* Uses the same fixed-corner approach as multi-selection resize
|
|
5962
5975
|
*/
|
|
5963
|
-
resize(t, e, o,
|
|
5964
|
-
if (!
|
|
5976
|
+
resize(t, e, o, s) {
|
|
5977
|
+
if (!s.childrenStartData || !s.width || !s.height)
|
|
5965
5978
|
return;
|
|
5966
|
-
const
|
|
5979
|
+
const i = e / s.width, a = o / s.height, n = (i + a) / 2;
|
|
5967
5980
|
let h, l;
|
|
5968
5981
|
switch (t) {
|
|
5969
5982
|
case "top-left":
|
|
5970
|
-
h =
|
|
5983
|
+
h = s.width / 2, l = s.height / 2;
|
|
5971
5984
|
break;
|
|
5972
5985
|
case "top-right":
|
|
5973
|
-
h = -
|
|
5986
|
+
h = -s.width / 2, l = s.height / 2;
|
|
5974
5987
|
break;
|
|
5975
5988
|
case "bottom-left":
|
|
5976
|
-
h =
|
|
5989
|
+
h = s.width / 2, l = -s.height / 2;
|
|
5977
5990
|
break;
|
|
5978
5991
|
case "bottom-right":
|
|
5979
|
-
h = -
|
|
5992
|
+
h = -s.width / 2, l = -s.height / 2;
|
|
5980
5993
|
break;
|
|
5981
5994
|
default:
|
|
5982
5995
|
h = 0, l = 0;
|
|
5983
5996
|
}
|
|
5984
|
-
const c = -
|
|
5997
|
+
const c = -s.rotation * Math.PI / 180, g = Math.cos(c), d = Math.sin(c), f = s.x + (h * g - l * d), u = s.y + (h * d + l * g);
|
|
5985
5998
|
this.children.forEach((y, x) => {
|
|
5986
|
-
const b =
|
|
5999
|
+
const b = s.childrenStartData[x], S = b.x - f, v = b.y - u, w = f + S * n, T = u + v * n;
|
|
5987
6000
|
if (y.x = w, y.y = T, y instanceof pt) {
|
|
5988
6001
|
const F = b.transformData, A = F.width * n, M = F.height * n;
|
|
5989
6002
|
y.transformData.width = A, y.transformData.height = M;
|
|
@@ -5994,8 +6007,8 @@ class ut extends Q {
|
|
|
5994
6007
|
const F = (b.width ?? 0) * n, A = (b.height ?? 0) * n;
|
|
5995
6008
|
y.resize(t, F, A, b);
|
|
5996
6009
|
}
|
|
5997
|
-
}), this._baseBBoxWidth =
|
|
5998
|
-
const m =
|
|
6010
|
+
}), this._baseBBoxWidth = s.width * n, this._baseBBoxHeight = s.height * n;
|
|
6011
|
+
const m = s.x - f, p = s.y - u;
|
|
5999
6012
|
this.x = f + m * n, this.y = u + p * n, this._rotationCenterX = this.x, this._rotationCenterY = this.y;
|
|
6000
6013
|
}
|
|
6001
6014
|
/**
|
|
@@ -6003,16 +6016,16 @@ class ut extends Q {
|
|
|
6003
6016
|
* Use cached base dimensions instead of axis-aligned bbox for consistency with visual border
|
|
6004
6017
|
*/
|
|
6005
6018
|
getTransformStartData() {
|
|
6006
|
-
const t = this._baseBBoxWidth > 0 ? this._baseBBoxWidth : this.getBoundingBox().width, e = this._baseBBoxHeight > 0 ? this._baseBBoxHeight : this.getBoundingBox().height, o = this._rotationCenterX || this.x,
|
|
6019
|
+
const t = this._baseBBoxWidth > 0 ? this._baseBBoxWidth : this.getBoundingBox().width, e = this._baseBBoxHeight > 0 ? this._baseBBoxHeight : this.getBoundingBox().height, o = this._rotationCenterX || this.x, s = this._rotationCenterY || this.y;
|
|
6007
6020
|
return {
|
|
6008
6021
|
id: this.id,
|
|
6009
6022
|
x: o,
|
|
6010
|
-
y:
|
|
6023
|
+
y: s,
|
|
6011
6024
|
width: t,
|
|
6012
6025
|
height: e,
|
|
6013
6026
|
rotation: this.rotation,
|
|
6014
6027
|
transformData: this.transformData,
|
|
6015
|
-
childrenStartData: this.children.map((
|
|
6028
|
+
childrenStartData: this.children.map((i) => i.getTransformStartData())
|
|
6016
6029
|
};
|
|
6017
6030
|
}
|
|
6018
6031
|
/**
|
|
@@ -6020,10 +6033,10 @@ class ut extends Q {
|
|
|
6020
6033
|
* This allows clicking anywhere within the selection border to drag the group
|
|
6021
6034
|
*/
|
|
6022
6035
|
hitTest(t, e) {
|
|
6023
|
-
const o = this.getOrientedBoundingBox(),
|
|
6036
|
+
const o = this.getOrientedBoundingBox(), s = this._rotationCenterX || this.x, i = this._rotationCenterY || this.y;
|
|
6024
6037
|
if (this.rotation === 0)
|
|
6025
6038
|
return t >= o.x && t <= o.x + o.width && e >= o.y && e <= o.y + o.height;
|
|
6026
|
-
const a = this.rotation * Math.PI / 180, n = Math.cos(a), h = Math.sin(a), l = t -
|
|
6039
|
+
const a = this.rotation * Math.PI / 180, n = Math.cos(a), h = Math.sin(a), l = t - s, c = e - i, g = s + (l * n - c * h), d = i + (l * h + c * n);
|
|
6027
6040
|
return g >= o.x && g <= o.x + o.width && d >= o.y && d <= o.y + o.height;
|
|
6028
6041
|
}
|
|
6029
6042
|
/**
|
|
@@ -6057,7 +6070,13 @@ class ut extends Q {
|
|
|
6057
6070
|
// Children are element instances here; the constructor handles both instances and configs
|
|
6058
6071
|
children: t
|
|
6059
6072
|
});
|
|
6060
|
-
return e._baseBBoxWidth = this._baseBBoxWidth, e._baseBBoxHeight = this._baseBBoxHeight, e._rotationCenterX = this._rotationCenterX, e._rotationCenterY = this._rotationCenterY, e.opacity = this.opacity, e.name = this.name, e.visible = this.visible, e.locked = this.locked, this.blendMode && (e.blendMode = this.blendMode), this.knockoutParts && (e.knockoutParts = { ...this.knockoutParts }), this.stroke && (e.stroke = {
|
|
6073
|
+
return e._baseBBoxWidth = this._baseBBoxWidth, e._baseBBoxHeight = this._baseBBoxHeight, e._rotationCenterX = this._rotationCenterX, e._rotationCenterY = this._rotationCenterY, e.opacity = this.opacity, e.name = this.name, e.visible = this.visible, e.locked = this.locked, this.blendMode && (e.blendMode = this.blendMode), this.knockoutParts && (e.knockoutParts = { ...this.knockoutParts }), this.stroke && (e.stroke = {
|
|
6074
|
+
...this.stroke,
|
|
6075
|
+
...this.stroke.dashArray && { dashArray: [...this.stroke.dashArray] }
|
|
6076
|
+
}), this.masks && (e.masks = this.masks.map((o) => ({
|
|
6077
|
+
...o,
|
|
6078
|
+
maskElement: structuredClone(o.maskElement)
|
|
6079
|
+
}))), this.distressEffect && (e.distressEffect = { ...this.distressEffect }), e;
|
|
6061
6080
|
}
|
|
6062
6081
|
/**
|
|
6063
6082
|
* Add a child to the group
|
|
@@ -6084,9 +6103,9 @@ class ut extends Q {
|
|
|
6084
6103
|
*/
|
|
6085
6104
|
hitTestChild(t, e) {
|
|
6086
6105
|
for (let o = this.children.length - 1; o >= 0; o--) {
|
|
6087
|
-
const
|
|
6088
|
-
if (
|
|
6089
|
-
return
|
|
6106
|
+
const s = this.children[o];
|
|
6107
|
+
if (s.hitTest(t, e))
|
|
6108
|
+
return s;
|
|
6090
6109
|
}
|
|
6091
6110
|
return null;
|
|
6092
6111
|
}
|
|
@@ -6131,8 +6150,8 @@ class Z {
|
|
|
6131
6150
|
getAllByName(t) {
|
|
6132
6151
|
const e = [];
|
|
6133
6152
|
for (const o of this.order) {
|
|
6134
|
-
const
|
|
6135
|
-
|
|
6153
|
+
const s = this.byId.get(o);
|
|
6154
|
+
s && s.name === t && e.push(s);
|
|
6136
6155
|
}
|
|
6137
6156
|
return e;
|
|
6138
6157
|
}
|
|
@@ -6153,8 +6172,8 @@ class Z {
|
|
|
6153
6172
|
const o = this.clone();
|
|
6154
6173
|
if (t !== e.id) {
|
|
6155
6174
|
o.byId.delete(t);
|
|
6156
|
-
const
|
|
6157
|
-
|
|
6175
|
+
const s = o.order.indexOf(t);
|
|
6176
|
+
s !== -1 && (o.order[s] = e.id);
|
|
6158
6177
|
}
|
|
6159
6178
|
return o.byId.set(e.id, e), o;
|
|
6160
6179
|
}
|
|
@@ -6167,8 +6186,8 @@ class Z {
|
|
|
6167
6186
|
insertAfter(t, e) {
|
|
6168
6187
|
const o = this.clone();
|
|
6169
6188
|
o.byId.set(t.id, t);
|
|
6170
|
-
const
|
|
6171
|
-
return
|
|
6189
|
+
const s = o.order.indexOf(e);
|
|
6190
|
+
return s !== -1 ? o.order.splice(s + 1, 0, t.id) : o.order.push(t.id), o;
|
|
6172
6191
|
}
|
|
6173
6192
|
/** Remove an element by ID. */
|
|
6174
6193
|
remove(t) {
|
|
@@ -6179,7 +6198,7 @@ class Z {
|
|
|
6179
6198
|
/** Reorder element to a new index in the render order. */
|
|
6180
6199
|
reorder(t, e) {
|
|
6181
6200
|
const o = this.clone();
|
|
6182
|
-
return o.order = o.order.filter((
|
|
6201
|
+
return o.order = o.order.filter((s) => s !== t), o.order.splice(e, 0, t), o;
|
|
6183
6202
|
}
|
|
6184
6203
|
/**
|
|
6185
6204
|
* Apply a batch update: replace elements whose IDs match.
|
|
@@ -6247,9 +6266,9 @@ class U {
|
|
|
6247
6266
|
throw new Error("Command.undo() must be implemented");
|
|
6248
6267
|
}
|
|
6249
6268
|
}
|
|
6250
|
-
class
|
|
6251
|
-
constructor(t, e, o,
|
|
6252
|
-
super(), this.elementId = t, this.oldElement = e ? e.clone() : null, this.newElement = o ? o.clone() : null, this.onUpdate =
|
|
6269
|
+
class ts extends U {
|
|
6270
|
+
constructor(t, e, o, s) {
|
|
6271
|
+
super(), this.elementId = t, this.oldElement = e ? e.clone() : null, this.newElement = o ? o.clone() : null, this.onUpdate = s;
|
|
6253
6272
|
}
|
|
6254
6273
|
execute() {
|
|
6255
6274
|
this.newElement && this.onUpdate(this.newElement);
|
|
@@ -6258,7 +6277,7 @@ class ti extends U {
|
|
|
6258
6277
|
this.oldElement && this.onUpdate(this.oldElement);
|
|
6259
6278
|
}
|
|
6260
6279
|
}
|
|
6261
|
-
class
|
|
6280
|
+
class es extends U {
|
|
6262
6281
|
constructor(t, e, o) {
|
|
6263
6282
|
super(), this.element = t.clone(), this.onAdd = e, this.onRemove = o;
|
|
6264
6283
|
}
|
|
@@ -6269,7 +6288,7 @@ class ei extends U {
|
|
|
6269
6288
|
this.onRemove(this.element.id);
|
|
6270
6289
|
}
|
|
6271
6290
|
}
|
|
6272
|
-
class
|
|
6291
|
+
class os extends U {
|
|
6273
6292
|
constructor(t, e, o) {
|
|
6274
6293
|
super(), this.element = t.clone(), this.onAdd = e, this.onRemove = o;
|
|
6275
6294
|
}
|
|
@@ -6357,7 +6376,7 @@ class ct {
|
|
|
6357
6376
|
};
|
|
6358
6377
|
}
|
|
6359
6378
|
}
|
|
6360
|
-
class
|
|
6379
|
+
class ss extends U {
|
|
6361
6380
|
constructor(t, e) {
|
|
6362
6381
|
super(), this.artboard = t.clone(), this.artboardManager = e;
|
|
6363
6382
|
}
|
|
@@ -6377,7 +6396,7 @@ class ii extends U {
|
|
|
6377
6396
|
this.artboardManager.deleteArtboard(this.artboard.id);
|
|
6378
6397
|
}
|
|
6379
6398
|
}
|
|
6380
|
-
class
|
|
6399
|
+
class is extends U {
|
|
6381
6400
|
constructor(t, e) {
|
|
6382
6401
|
super(), this.artboard = t.clone(), this.artboardManager = e, this.elementsOnArtboard = t.getElementIds();
|
|
6383
6402
|
}
|
|
@@ -6400,9 +6419,9 @@ class si extends U {
|
|
|
6400
6419
|
});
|
|
6401
6420
|
}
|
|
6402
6421
|
}
|
|
6403
|
-
class
|
|
6404
|
-
constructor(t, e, o,
|
|
6405
|
-
super(), this.artboardId = t, this.oldProperties = { ...e }, this.newProperties = { ...o }, this.artboardManager =
|
|
6422
|
+
class rs extends U {
|
|
6423
|
+
constructor(t, e, o, s) {
|
|
6424
|
+
super(), this.artboardId = t, this.oldProperties = { ...e }, this.newProperties = { ...o }, this.artboardManager = s;
|
|
6406
6425
|
}
|
|
6407
6426
|
execute() {
|
|
6408
6427
|
this.artboardManager.updateArtboard(this.artboardId, this.newProperties);
|
|
@@ -6411,9 +6430,9 @@ class ri extends U {
|
|
|
6411
6430
|
this.artboardManager.updateArtboard(this.artboardId, this.oldProperties);
|
|
6412
6431
|
}
|
|
6413
6432
|
}
|
|
6414
|
-
class
|
|
6415
|
-
constructor(t, e, o,
|
|
6416
|
-
super(), this.draggedId = t, this.targetId = e, this.position = o, this.oldOrder = [...
|
|
6433
|
+
class ns extends U {
|
|
6434
|
+
constructor(t, e, o, s, i) {
|
|
6435
|
+
super(), this.draggedId = t, this.targetId = e, this.position = o, this.oldOrder = [...s], this.onReorder = i, this.newOrder = this.calculateNewOrder();
|
|
6417
6436
|
}
|
|
6418
6437
|
calculateNewOrder() {
|
|
6419
6438
|
const t = [...this.oldOrder], e = t.indexOf(this.draggedId);
|
|
@@ -6421,8 +6440,8 @@ class ni extends U {
|
|
|
6421
6440
|
t.splice(e, 1);
|
|
6422
6441
|
const o = t.indexOf(this.targetId);
|
|
6423
6442
|
if (o === -1) return t;
|
|
6424
|
-
const
|
|
6425
|
-
return t.splice(
|
|
6443
|
+
const s = this.position === "before" ? o : o + 1;
|
|
6444
|
+
return t.splice(s, 0, this.draggedId), t;
|
|
6426
6445
|
}
|
|
6427
6446
|
execute() {
|
|
6428
6447
|
this.onReorder(this.newOrder);
|
|
@@ -6432,7 +6451,7 @@ class ni extends U {
|
|
|
6432
6451
|
}
|
|
6433
6452
|
}
|
|
6434
6453
|
const Ge = mt("HybridHistoryManager");
|
|
6435
|
-
class
|
|
6454
|
+
class as {
|
|
6436
6455
|
constructor(t, e = 50) {
|
|
6437
6456
|
this.commandExecutedCallbacks = [], this.globalHistory = new ct(e), this.artboardHistories = /* @__PURE__ */ new Map(), this.lastOperation = null, this.artboardManager = t, this.maxHistorySize = e;
|
|
6438
6457
|
}
|
|
@@ -6450,11 +6469,11 @@ class ai {
|
|
|
6450
6469
|
* Notify all callbacks that a command was executed
|
|
6451
6470
|
*/
|
|
6452
6471
|
notifyCommandExecuted(t, e, o) {
|
|
6453
|
-
for (const
|
|
6472
|
+
for (const s of this.commandExecutedCallbacks)
|
|
6454
6473
|
try {
|
|
6455
|
-
|
|
6456
|
-
} catch (
|
|
6457
|
-
Ge.error("Error in command executed callback:",
|
|
6474
|
+
s(t, e, o);
|
|
6475
|
+
} catch (i) {
|
|
6476
|
+
Ge.error("Error in command executed callback:", i);
|
|
6458
6477
|
}
|
|
6459
6478
|
}
|
|
6460
6479
|
/**
|
|
@@ -6493,8 +6512,8 @@ class ai {
|
|
|
6493
6512
|
artboardId: t,
|
|
6494
6513
|
timestamp: Date.now()
|
|
6495
6514
|
};
|
|
6496
|
-
const
|
|
6497
|
-
this.notifyCommandExecuted(
|
|
6515
|
+
const s = o.history[o.currentIndex];
|
|
6516
|
+
this.notifyCommandExecuted(s, "artboard", t);
|
|
6498
6517
|
}
|
|
6499
6518
|
/**
|
|
6500
6519
|
* Execute a command on a specific artboard
|
|
@@ -6660,12 +6679,12 @@ class ai {
|
|
|
6660
6679
|
*/
|
|
6661
6680
|
getState() {
|
|
6662
6681
|
const t = this.globalHistory.getState(), e = /* @__PURE__ */ new Map();
|
|
6663
|
-
return this.artboardHistories.forEach((o,
|
|
6664
|
-
const
|
|
6665
|
-
e.set(
|
|
6666
|
-
canUndo:
|
|
6667
|
-
canRedo:
|
|
6668
|
-
historySize:
|
|
6682
|
+
return this.artboardHistories.forEach((o, s) => {
|
|
6683
|
+
const i = o.getState();
|
|
6684
|
+
e.set(s, {
|
|
6685
|
+
canUndo: i.canUndo,
|
|
6686
|
+
canRedo: i.canRedo,
|
|
6687
|
+
historySize: i.historySize
|
|
6669
6688
|
});
|
|
6670
6689
|
}), {
|
|
6671
6690
|
global: {
|
|
@@ -6743,8 +6762,8 @@ class Ve {
|
|
|
6743
6762
|
evictOldestFont() {
|
|
6744
6763
|
if (this.fontCache.size <= this.MAX_CACHE_SIZE) return;
|
|
6745
6764
|
let t = null, e = Date.now();
|
|
6746
|
-
this.fontCache.forEach((o,
|
|
6747
|
-
o.timestamp < e && (e = o.timestamp, t =
|
|
6765
|
+
this.fontCache.forEach((o, s) => {
|
|
6766
|
+
o.timestamp < e && (e = o.timestamp, t = s);
|
|
6748
6767
|
}), t && this.fontCache.delete(t);
|
|
6749
6768
|
}
|
|
6750
6769
|
/**
|
|
@@ -6764,7 +6783,7 @@ class Ve {
|
|
|
6764
6783
|
*/
|
|
6765
6784
|
async extractFontFileUrl(t, e = 400) {
|
|
6766
6785
|
try {
|
|
6767
|
-
const o = this.getGoogleFontUrl(t, e),
|
|
6786
|
+
const o = this.getGoogleFontUrl(t, e), i = await (await fetch(o)).text(), a = /@font-face\s*{([^}]*)}/g, n = Array.from(i.matchAll(a));
|
|
6768
6787
|
if (n.length === 0)
|
|
6769
6788
|
return N.warn("No @font-face found in CSS"), null;
|
|
6770
6789
|
let h = null, l = -1;
|
|
@@ -6789,24 +6808,24 @@ class Ve {
|
|
|
6789
6808
|
const o = `${t}-${e}`;
|
|
6790
6809
|
if (this.failedFonts.has(o))
|
|
6791
6810
|
return null;
|
|
6792
|
-
const
|
|
6793
|
-
if (
|
|
6794
|
-
return
|
|
6811
|
+
const s = this.fontCache.get(o);
|
|
6812
|
+
if (s && Date.now() - s.timestamp < this.CACHE_DURATION)
|
|
6813
|
+
return s.timestamp = Date.now(), s.font;
|
|
6795
6814
|
try {
|
|
6796
|
-
const
|
|
6797
|
-
if (!
|
|
6815
|
+
const i = await this.extractFontFileUrl(t, e);
|
|
6816
|
+
if (!i)
|
|
6798
6817
|
return this.failedFonts.add(o), null;
|
|
6799
|
-
const a = await fetch(
|
|
6818
|
+
const a = await fetch(i);
|
|
6800
6819
|
if (!a.ok)
|
|
6801
6820
|
return N.error(`Font fetch failed: ${a.status} ${a.statusText}`), this.failedFonts.add(o), null;
|
|
6802
6821
|
const n = await a.arrayBuffer(), h = new Uint8Array(n), c = (await $e()).create(h), g = "fonts" in c ? c.fonts[0] : c;
|
|
6803
6822
|
return this.fontCache.set(o, {
|
|
6804
6823
|
font: g,
|
|
6805
|
-
url:
|
|
6824
|
+
url: i,
|
|
6806
6825
|
timestamp: Date.now()
|
|
6807
6826
|
}), this.evictOldestFont(), g;
|
|
6808
|
-
} catch (
|
|
6809
|
-
return N.error(`Error loading font ${t}:`,
|
|
6827
|
+
} catch (i) {
|
|
6828
|
+
return N.error(`Error loading font ${t}:`, i), this.failedFonts.add(o), null;
|
|
6810
6829
|
}
|
|
6811
6830
|
}
|
|
6812
6831
|
/**
|
|
@@ -6814,8 +6833,8 @@ class Ve {
|
|
|
6814
6833
|
* Returns null if font is not cached - font should be pre-loaded before rendering
|
|
6815
6834
|
*/
|
|
6816
6835
|
getFontSync(t, e = 400) {
|
|
6817
|
-
const o = `${t}-${e}`,
|
|
6818
|
-
return
|
|
6836
|
+
const o = `${t}-${e}`, s = this.fontCache.get(o);
|
|
6837
|
+
return s && Date.now() - s.timestamp < this.CACHE_DURATION ? (s.timestamp = Date.now(), s.font) : null;
|
|
6819
6838
|
}
|
|
6820
6839
|
/**
|
|
6821
6840
|
* Clear font cache (useful for debugging or forcing reload)
|
|
@@ -6835,13 +6854,13 @@ class Ve {
|
|
|
6835
6854
|
var n, h;
|
|
6836
6855
|
if (this.isSystemFont(t))
|
|
6837
6856
|
return [];
|
|
6838
|
-
const
|
|
6839
|
-
if (!
|
|
6857
|
+
const s = await this.loadFont(t, e);
|
|
6858
|
+
if (!s)
|
|
6840
6859
|
return [];
|
|
6841
|
-
const
|
|
6860
|
+
const i = [], a = Math.min(s.numGlyphs, o);
|
|
6842
6861
|
for (let l = 0; l < a; l++)
|
|
6843
6862
|
try {
|
|
6844
|
-
const c =
|
|
6863
|
+
const c = s.getGlyph(l);
|
|
6845
6864
|
if (!c || !c.name || c.name === ".notdef" || c.name.startsWith(".null"))
|
|
6846
6865
|
continue;
|
|
6847
6866
|
const g = c.codePoints || [];
|
|
@@ -6866,42 +6885,42 @@ class Ve {
|
|
|
6866
6885
|
const m = c.name.toLowerCase();
|
|
6867
6886
|
if (m.includes("swash") || m.includes("cswh") ? u = "swash" : c.name.match(/\.(alt|ss\d+|cv\d+|salt|ornament)/) || c.name.match(/_\d+$/) ? u = "stylistic" : m.match(/liga|dlig/) && (u = "ligature"), u === "default")
|
|
6868
6887
|
continue;
|
|
6869
|
-
d && d.length > 0 &&
|
|
6888
|
+
d && d.length > 0 && i.push({
|
|
6870
6889
|
glyphIndex: c.id,
|
|
6871
6890
|
unicode: d,
|
|
6872
6891
|
name: f,
|
|
6873
6892
|
category: u,
|
|
6874
|
-
previewDataUrl: this.generateGlyphPreview(
|
|
6893
|
+
previewDataUrl: this.generateGlyphPreview(s, c.id, 80)
|
|
6875
6894
|
});
|
|
6876
6895
|
} catch {
|
|
6877
6896
|
}
|
|
6878
|
-
return
|
|
6897
|
+
return i;
|
|
6879
6898
|
}
|
|
6880
6899
|
/**
|
|
6881
6900
|
* Get glyph alternates for a specific character
|
|
6882
6901
|
*/
|
|
6883
6902
|
async getGlyphAlternates(t, e, o = 400) {
|
|
6884
6903
|
var l, c, g, d;
|
|
6885
|
-
const
|
|
6886
|
-
if (!
|
|
6904
|
+
const s = await this.loadFont(t, o);
|
|
6905
|
+
if (!s)
|
|
6887
6906
|
return [];
|
|
6888
|
-
const
|
|
6907
|
+
const i = [], a = e.codePointAt(0);
|
|
6889
6908
|
if (a === void 0)
|
|
6890
6909
|
return [];
|
|
6891
|
-
const n =
|
|
6892
|
-
n &&
|
|
6910
|
+
const n = s.glyphForCodePoint(a);
|
|
6911
|
+
n && i.push({
|
|
6893
6912
|
glyphIndex: n.id,
|
|
6894
6913
|
unicode: e,
|
|
6895
6914
|
name: n.name || "Default",
|
|
6896
6915
|
category: "default",
|
|
6897
|
-
previewDataUrl: this.generateGlyphPreview(
|
|
6916
|
+
previewDataUrl: this.generateGlyphPreview(s, n.id, 80)
|
|
6898
6917
|
});
|
|
6899
6918
|
const h = n == null ? void 0 : n.name;
|
|
6900
6919
|
if (h) {
|
|
6901
6920
|
let f = 0;
|
|
6902
|
-
for (let u = 0; u <
|
|
6921
|
+
for (let u = 0; u < s.numGlyphs; u++)
|
|
6903
6922
|
try {
|
|
6904
|
-
const m =
|
|
6923
|
+
const m = s.getGlyph(u);
|
|
6905
6924
|
if (!m || !m.name) continue;
|
|
6906
6925
|
if ([
|
|
6907
6926
|
new RegExp(`^${h}\\.(swash|alt|ss\\d+|salt|ornament)`, "i"),
|
|
@@ -6919,19 +6938,19 @@ class Ve {
|
|
|
6919
6938
|
const b = (c = m.name.match(/\.ss(\d+)/)) == null ? void 0 : c[1];
|
|
6920
6939
|
x = `${e} Stylistic Set ${b}`;
|
|
6921
6940
|
}
|
|
6922
|
-
|
|
6941
|
+
i.push({
|
|
6923
6942
|
glyphIndex: m.id,
|
|
6924
6943
|
unicode: e,
|
|
6925
6944
|
name: x,
|
|
6926
6945
|
category: "stylistic",
|
|
6927
|
-
previewDataUrl: this.generateGlyphPreview(
|
|
6946
|
+
previewDataUrl: this.generateGlyphPreview(s, m.id, 80)
|
|
6928
6947
|
});
|
|
6929
6948
|
}
|
|
6930
6949
|
} catch {
|
|
6931
6950
|
}
|
|
6932
6951
|
}
|
|
6933
|
-
if (
|
|
6934
|
-
const f =
|
|
6952
|
+
if (s.GSUB) {
|
|
6953
|
+
const f = s.GSUB;
|
|
6935
6954
|
if (f.featureList)
|
|
6936
6955
|
for (const u of f.featureList) {
|
|
6937
6956
|
const m = u.tag;
|
|
@@ -6945,12 +6964,12 @@ class Ve {
|
|
|
6945
6964
|
if (!b) continue;
|
|
6946
6965
|
if (this.getCoverageIndex(b, n.id) !== -1) {
|
|
6947
6966
|
const v = this.getSubstituteGlyph(x, n.id);
|
|
6948
|
-
v !== null &&
|
|
6967
|
+
v !== null && i.push({
|
|
6949
6968
|
glyphIndex: v,
|
|
6950
6969
|
unicode: e,
|
|
6951
6970
|
name: `${e} (${m})`,
|
|
6952
6971
|
category: this.categorizeFeature(m),
|
|
6953
|
-
previewDataUrl: this.generateGlyphPreview(
|
|
6972
|
+
previewDataUrl: this.generateGlyphPreview(s, v, 80)
|
|
6954
6973
|
});
|
|
6955
6974
|
}
|
|
6956
6975
|
}
|
|
@@ -6963,12 +6982,12 @@ class Ve {
|
|
|
6963
6982
|
const w = v.alternateSets[S];
|
|
6964
6983
|
if (w)
|
|
6965
6984
|
for (const T of w)
|
|
6966
|
-
|
|
6985
|
+
i.push({
|
|
6967
6986
|
glyphIndex: T,
|
|
6968
6987
|
unicode: e,
|
|
6969
6988
|
name: `${e} (${m} alt)`,
|
|
6970
6989
|
category: this.categorizeFeature(m),
|
|
6971
|
-
previewDataUrl: this.generateGlyphPreview(
|
|
6990
|
+
previewDataUrl: this.generateGlyphPreview(s, T, 80)
|
|
6972
6991
|
});
|
|
6973
6992
|
}
|
|
6974
6993
|
}
|
|
@@ -6976,7 +6995,7 @@ class Ve {
|
|
|
6976
6995
|
}
|
|
6977
6996
|
}
|
|
6978
6997
|
}
|
|
6979
|
-
return
|
|
6998
|
+
return i;
|
|
6980
6999
|
}
|
|
6981
7000
|
/**
|
|
6982
7001
|
* Get available OpenType features for a font
|
|
@@ -6986,38 +7005,38 @@ class Ve {
|
|
|
6986
7005
|
if (!o)
|
|
6987
7006
|
return N.warn(`Font ${t} failed to load`), [];
|
|
6988
7007
|
try {
|
|
6989
|
-
const
|
|
7008
|
+
const s = [];
|
|
6990
7009
|
if (o.GSUB && o.GSUB.featureList) {
|
|
6991
|
-
const
|
|
7010
|
+
const i = /* @__PURE__ */ new Set();
|
|
6992
7011
|
for (const a of o.GSUB.featureList)
|
|
6993
|
-
a.tag &&
|
|
6994
|
-
|
|
7012
|
+
a.tag && i.add(a.tag);
|
|
7013
|
+
s.push(...Array.from(i));
|
|
6995
7014
|
}
|
|
6996
7015
|
if (o.GPOS && o.GPOS.featureList) {
|
|
6997
|
-
const
|
|
7016
|
+
const i = /* @__PURE__ */ new Set();
|
|
6998
7017
|
for (const a of o.GPOS.featureList)
|
|
6999
|
-
a.tag &&
|
|
7000
|
-
|
|
7018
|
+
a.tag && i.add(a.tag);
|
|
7019
|
+
s.push(...Array.from(i));
|
|
7001
7020
|
}
|
|
7002
|
-
return
|
|
7003
|
-
} catch (
|
|
7004
|
-
return N.error(`Error getting features for ${t}:`,
|
|
7021
|
+
return s;
|
|
7022
|
+
} catch (s) {
|
|
7023
|
+
return N.error(`Error getting features for ${t}:`, s), [];
|
|
7005
7024
|
}
|
|
7006
7025
|
}
|
|
7007
7026
|
/**
|
|
7008
7027
|
* Generate a preview image for a glyph
|
|
7009
7028
|
*/
|
|
7010
7029
|
generateGlyphPreview(t, e, o = 80) {
|
|
7011
|
-
const
|
|
7012
|
-
|
|
7013
|
-
const
|
|
7014
|
-
if (!
|
|
7030
|
+
const s = document.createElement("canvas");
|
|
7031
|
+
s.width = o, s.height = o;
|
|
7032
|
+
const i = s.getContext("2d");
|
|
7033
|
+
if (!i)
|
|
7015
7034
|
return "";
|
|
7016
7035
|
try {
|
|
7017
7036
|
const a = t.getGlyph(e);
|
|
7018
7037
|
if (!a)
|
|
7019
7038
|
return "";
|
|
7020
|
-
|
|
7039
|
+
i.clearRect(0, 0, o, o);
|
|
7021
7040
|
const n = a.bbox;
|
|
7022
7041
|
if (!n)
|
|
7023
7042
|
return "";
|
|
@@ -7028,7 +7047,7 @@ class Ve {
|
|
|
7028
7047
|
if (!p)
|
|
7029
7048
|
return "";
|
|
7030
7049
|
const y = new Path2D(p);
|
|
7031
|
-
return
|
|
7050
|
+
return i.save(), i.translate(u, m), i.scale(g, -g), i.translate(-d, -f), i.fillStyle = "#000000", i.fill(y), i.restore(), s.toDataURL("image/png");
|
|
7032
7051
|
} catch (a) {
|
|
7033
7052
|
return N.error("Error generating glyph preview:", a), "";
|
|
7034
7053
|
}
|
|
@@ -7091,10 +7110,10 @@ class Ve {
|
|
|
7091
7110
|
return t.glyphs.indexOf(e);
|
|
7092
7111
|
if (t.format === 2 && t.ranges) {
|
|
7093
7112
|
const o = t.ranges;
|
|
7094
|
-
for (let
|
|
7095
|
-
const
|
|
7096
|
-
if (e >=
|
|
7097
|
-
return
|
|
7113
|
+
for (let s = 0; s < o.length; s++) {
|
|
7114
|
+
const i = o[s];
|
|
7115
|
+
if (e >= i.start && e <= i.end)
|
|
7116
|
+
return i.index + (e - i.start);
|
|
7098
7117
|
}
|
|
7099
7118
|
}
|
|
7100
7119
|
return -1;
|
|
@@ -7107,9 +7126,9 @@ class Ve {
|
|
|
7107
7126
|
if (t.substFormat === 1 && typeof t.deltaGlyphId == "number")
|
|
7108
7127
|
return e + t.deltaGlyphId;
|
|
7109
7128
|
if (t.substFormat === 2 && t.substitute) {
|
|
7110
|
-
const o = this.getCoverageIndex(t.coverage, e),
|
|
7111
|
-
if (o !== -1 &&
|
|
7112
|
-
return
|
|
7129
|
+
const o = this.getCoverageIndex(t.coverage, e), s = t.substitute;
|
|
7130
|
+
if (o !== -1 && s[o] !== void 0)
|
|
7131
|
+
return s[o];
|
|
7113
7132
|
}
|
|
7114
7133
|
return null;
|
|
7115
7134
|
}
|
|
@@ -7120,9 +7139,9 @@ class Ve {
|
|
|
7120
7139
|
const o = await this.loadFont(t, e);
|
|
7121
7140
|
if (!o)
|
|
7122
7141
|
return 0;
|
|
7123
|
-
let
|
|
7124
|
-
const
|
|
7125
|
-
for (let a = 0; a <
|
|
7142
|
+
let s = 0;
|
|
7143
|
+
const i = Math.min(o.numGlyphs, 1500);
|
|
7144
|
+
for (let a = 0; a < i; a++)
|
|
7126
7145
|
try {
|
|
7127
7146
|
const n = o.getGlyph(a);
|
|
7128
7147
|
if (!n || !n.name || n.name === ".notdef" || n.name.startsWith(".null"))
|
|
@@ -7135,10 +7154,10 @@ class Ve {
|
|
|
7135
7154
|
}
|
|
7136
7155
|
let c = "default";
|
|
7137
7156
|
const g = n.name.toLowerCase();
|
|
7138
|
-
g.includes("swash") || g.includes("cswh") ? c = "swash" : n.name.match(/\.(alt|ss\d+|cv\d+|salt|ornament)/) || n.name.match(/_\d+$/) ? c = "stylistic" : g.match(/liga|dlig/) && (c = "ligature"), c !== "default" && l && l.length > 0 &&
|
|
7157
|
+
g.includes("swash") || g.includes("cswh") ? c = "swash" : n.name.match(/\.(alt|ss\d+|cv\d+|salt|ornament)/) || n.name.match(/_\d+$/) ? c = "stylistic" : g.match(/liga|dlig/) && (c = "ligature"), c !== "default" && l && l.length > 0 && s++;
|
|
7139
7158
|
} catch {
|
|
7140
7159
|
}
|
|
7141
|
-
return
|
|
7160
|
+
return s;
|
|
7142
7161
|
}
|
|
7143
7162
|
/**
|
|
7144
7163
|
* Get cache statistics
|
|
@@ -7150,7 +7169,7 @@ class Ve {
|
|
|
7150
7169
|
};
|
|
7151
7170
|
}
|
|
7152
7171
|
}
|
|
7153
|
-
const
|
|
7172
|
+
const hs = new Ve();
|
|
7154
7173
|
export {
|
|
7155
7174
|
be as $,
|
|
7156
7175
|
nt as A,
|
|
@@ -7166,14 +7185,14 @@ export {
|
|
|
7166
7185
|
Ie as K,
|
|
7167
7186
|
Z as L,
|
|
7168
7187
|
ze as M,
|
|
7169
|
-
|
|
7188
|
+
as as N,
|
|
7170
7189
|
Xe as O,
|
|
7171
7190
|
Mt as P,
|
|
7172
7191
|
ye as Q,
|
|
7173
7192
|
P as R,
|
|
7174
7193
|
Ft as S,
|
|
7175
7194
|
q as T,
|
|
7176
|
-
|
|
7195
|
+
ts as U,
|
|
7177
7196
|
ke as V,
|
|
7178
7197
|
We as W,
|
|
7179
7198
|
Uo as X,
|
|
@@ -7198,8 +7217,8 @@ export {
|
|
|
7198
7217
|
Ee as aE,
|
|
7199
7218
|
qo as aF,
|
|
7200
7219
|
uo as aG,
|
|
7201
|
-
|
|
7202
|
-
|
|
7220
|
+
so as aH,
|
|
7221
|
+
io as aI,
|
|
7203
7222
|
oo as aJ,
|
|
7204
7223
|
he as aK,
|
|
7205
7224
|
eo as aL,
|
|
@@ -7219,17 +7238,17 @@ export {
|
|
|
7219
7238
|
rt as aZ,
|
|
7220
7239
|
Co as aa,
|
|
7221
7240
|
J as ab,
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7241
|
+
es as ac,
|
|
7242
|
+
os as ad,
|
|
7243
|
+
ss as ae,
|
|
7244
|
+
is as af,
|
|
7245
|
+
rs as ag,
|
|
7246
|
+
ns as ah,
|
|
7228
7247
|
fe as ai,
|
|
7229
7248
|
ue as aj,
|
|
7230
7249
|
co as ak,
|
|
7231
7250
|
He as al,
|
|
7232
|
-
|
|
7251
|
+
it as am,
|
|
7233
7252
|
bo as an,
|
|
7234
7253
|
vt as ao,
|
|
7235
7254
|
zt as ap,
|
|
@@ -7267,6 +7286,6 @@ export {
|
|
|
7267
7286
|
ko as w,
|
|
7268
7287
|
Mo as x,
|
|
7269
7288
|
Dt as y,
|
|
7270
|
-
|
|
7289
|
+
hs as z
|
|
7271
7290
|
};
|
|
7272
|
-
//# sourceMappingURL=FontAnalyzer-
|
|
7291
|
+
//# sourceMappingURL=FontAnalyzer-PE6nysqE.js.map
|