@snowcone-app/canvas 0.16.0 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{CanvasStateV1-BQD8fCBU.js → CanvasStateV1-C6i6vU6p.js} +63 -63
- package/dist/{CanvasStateV1-BQD8fCBU.js.map → CanvasStateV1-C6i6vU6p.js.map} +1 -1
- package/dist/EditorCanvasImpl-C8SsT3C2.js +68 -0
- package/dist/EditorCanvasImpl-C8SsT3C2.js.map +1 -0
- package/dist/EditorContext-CyanYzo2.js +1131 -0
- package/dist/EditorContext-CyanYzo2.js.map +1 -0
- package/dist/{ImportManager-eotl7r5d.js → ElementFactory-C05JJkRp.js} +1510 -5121
- package/dist/ElementFactory-C05JJkRp.js.map +1 -0
- package/dist/{HybridHistoryManager-NL3zyEl4.js → HybridHistoryManager-Bht98XRv.js} +98 -98
- package/dist/{HybridHistoryManager-NL3zyEl4.js.map → HybridHistoryManager-Bht98XRv.js.map} +1 -1
- package/dist/ImportManager-kRYfIX-D.js +3617 -0
- package/dist/ImportManager-kRYfIX-D.js.map +1 -0
- package/dist/SnowconeCanvas-C3eZ9PP8.js +1047 -0
- package/dist/SnowconeCanvas-C3eZ9PP8.js.map +1 -0
- package/dist/ThemeContext-Rjz25x9X.js +75 -0
- package/dist/ThemeContext-Rjz25x9X.js.map +1 -0
- package/dist/UnifiedFontService-BAtqqkU4.js +1478 -0
- package/dist/UnifiedFontService-BAtqqkU4.js.map +1 -0
- package/dist/advanced.mjs +210 -207
- package/dist/advanced.mjs.map +1 -1
- package/dist/api/embed.d.ts +8 -4
- package/dist/api/testing.d.ts +1 -0
- package/dist/components/editor/EditorBuy.d.ts +49 -0
- package/dist/components/editor/EditorCanvas.d.ts +30 -0
- package/dist/components/editor/EditorCanvasImpl.d.ts +33 -0
- package/dist/components/editor/EditorPreview.d.ts +39 -0
- package/dist/components/editor/EditorRoot.d.ts +86 -0
- package/dist/components/editor/EditorTextField.d.ts +22 -0
- package/dist/components/editor/RootInternals.d.ts +77 -0
- package/dist/components/editor/designStateStore.d.ts +45 -0
- package/dist/components/editor/index.d.ts +23 -0
- package/dist/components/embed-realtime/RealtimeCanvas.d.ts +1 -1
- package/dist/components/embed-realtime/RealtimeEmbed.d.ts +5 -78
- package/dist/components/embed-realtime/RealtimeMockup.d.ts +5 -34
- package/dist/components/embed-realtime/context.d.ts +12 -2
- package/dist/components/embed-realtime/validateEmbed.d.ts +17 -3
- package/dist/design/design-builder.d.ts +81 -6
- package/dist/editorError-DMENTZ-3.js +19 -0
- package/dist/editorError-DMENTZ-3.js.map +1 -0
- package/dist/editorErrors-DbIEtCTt.js +29 -0
- package/dist/editorErrors-DbIEtCTt.js.map +1 -0
- package/dist/embed-B5kewSQY.js +738 -0
- package/dist/embed-B5kewSQY.js.map +1 -0
- package/dist/embed.mjs +38 -230
- package/dist/embed.mjs.map +1 -1
- package/dist/errors/editorError.d.ts +57 -0
- package/dist/iconify-D6eVIEy4.js +1089 -0
- package/dist/iconify-D6eVIEy4.js.map +1 -0
- package/dist/index.mjs +48 -46
- package/dist/index.mjs.map +1 -1
- package/dist/internals.mjs +105 -104
- package/dist/internals.mjs.map +1 -1
- package/dist/template-fields-GOM4MNfq.js +643 -0
- package/dist/template-fields-GOM4MNfq.js.map +1 -0
- package/dist/testing/editorErrors.d.ts +30 -0
- package/dist/testing.mjs +28 -23
- package/dist/testing.mjs.map +1 -1
- package/dist/{usePieceGuideBundle-Cyl695jv.js → usePieceGuideBundle-CGERAQJl.js} +2 -2
- package/dist/{usePieceGuideBundle-Cyl695jv.js.map → usePieceGuideBundle-CGERAQJl.js.map} +1 -1
- package/dist/validation-DEd6EOCP.js +19947 -0
- package/dist/validation-DEd6EOCP.js.map +1 -0
- package/dist/workers/export-worker.bundle.string.d.ts +1 -1
- package/package.json +12 -4
- package/dist/ImportManager-eotl7r5d.js.map +0 -1
- package/dist/ThemeContext-D9AaUw9v.js +0 -1200
- package/dist/ThemeContext-D9AaUw9v.js.map +0 -1
- package/dist/template-fields-PcSPApl5.js +0 -1632
- package/dist/template-fields-PcSPApl5.js.map +0 -1
- package/dist/validation-BpEod0Rn.js +0 -22953
- package/dist/validation-BpEod0Rn.js.map +0 -1
package/dist/internals.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { A as b, e as w, C as I, I as R, f as W, R as A, S as E, T as H } from "./ImportManager-kRYfIX-D.js";
|
|
2
|
+
import { D as p } from "./HybridHistoryManager-Bht98XRv.js";
|
|
3
|
+
import { E as F, H as L, J as X, K, L as Y, M as z, N as _, O as B, Q as J, U as N, W as V, V as U, X as Q, Y as Z, Z as $, _ as j, $ as q, a0 as G, a1 as m, c as x, a2 as D, a3 as rr, a4 as or, a5 as sr, a6 as ir, a7 as ar, a8 as er, a9 as nr, aa as tr, ab as hr, ac as dr, ad as cr, ae as fr, af as pr, ag as gr, ah as lr, ai as ur } from "./HybridHistoryManager-Bht98XRv.js";
|
|
4
|
+
import { D as kr, E as Mr, W as yr, c as Cr, a as vr, b as Sr, g as Pr, i as br, r as wr, d as Ir, e as Rr, t as Wr, u as Ar } from "./ElementFactory-C05JJkRp.js";
|
|
5
|
+
import { A as Hr, e as Or, C as Fr, S as Lr } from "./CanvasStateV1-C6i6vU6p.js";
|
|
6
|
+
function y(r, o) {
|
|
6
7
|
return !r.needsCropPixelConversion || r.cropWidth === void 0 ? r : {
|
|
7
8
|
...r,
|
|
8
9
|
cropX: (r.cropX ?? 0) * o.width,
|
|
@@ -12,19 +13,19 @@ function M(r, o) {
|
|
|
12
13
|
needsCropPixelConversion: !1
|
|
13
14
|
};
|
|
14
15
|
}
|
|
15
|
-
function
|
|
16
|
+
function C(r, o, c) {
|
|
16
17
|
var e, n;
|
|
17
18
|
r.save(), r.translate(o.x, o.y), o.rotation && r.rotate(-o.rotation * Math.PI / 180);
|
|
18
|
-
let
|
|
19
|
-
if (o.flipHorizontal && (
|
|
20
|
-
const
|
|
19
|
+
let a = 1, h = 1;
|
|
20
|
+
if (o.flipHorizontal && (a = -1), o.flipVertical && (h = -1), (a !== 1 || h !== 1) && r.scale(a, h), o.opacity !== void 0 && o.opacity !== 1 && (r.globalAlpha = o.opacity), o.borderRadius && o.borderRadius > 0) {
|
|
21
|
+
const i = Math.min(
|
|
21
22
|
o.borderRadius / 100 * Math.min(o.width, o.height),
|
|
22
23
|
o.width / 2,
|
|
23
24
|
o.height / 2
|
|
24
25
|
);
|
|
25
26
|
r.beginPath();
|
|
26
27
|
const s = -o.width / 2, t = -o.height / 2, d = o.width, f = o.height;
|
|
27
|
-
r.moveTo(s +
|
|
28
|
+
r.moveTo(s + i, t), r.lineTo(s + d - i, t), r.arcTo(s + d, t, s + d, t + i, i), r.lineTo(s + d, t + f - i), r.arcTo(s + d, t + f, s + d - i, t + f, i), r.lineTo(s + i, t + f), r.arcTo(s, t + f, s, t + f - i, i), r.lineTo(s, t + i), r.arcTo(s, t, s + i, t, i), r.closePath(), r.clip();
|
|
28
29
|
}
|
|
29
30
|
if (o.cropX !== void 0 && o.cropWidth !== void 0 ? r.drawImage(
|
|
30
31
|
c,
|
|
@@ -37,7 +38,7 @@ function v(r, o, c) {
|
|
|
37
38
|
o.width,
|
|
38
39
|
o.height
|
|
39
40
|
) : r.drawImage(c, -o.width / 2, -o.height / 2, o.width, o.height), r.restore(), (e = o.stroke) != null && e.enabled) {
|
|
40
|
-
const
|
|
41
|
+
const i = ((n = o.knockoutParts) == null ? void 0 : n.stroke) === !0, s = {
|
|
41
42
|
x: o.x,
|
|
42
43
|
y: o.y,
|
|
43
44
|
rotation: o.rotation,
|
|
@@ -50,7 +51,7 @@ function v(r, o, c) {
|
|
|
50
51
|
borderRadius: o.borderRadius || 0
|
|
51
52
|
}
|
|
52
53
|
};
|
|
53
|
-
if (
|
|
54
|
+
if (i) {
|
|
54
55
|
const t = r.canvas;
|
|
55
56
|
let d;
|
|
56
57
|
if (typeof OffscreenCanvas < "u")
|
|
@@ -71,20 +72,20 @@ function v(r, o, c) {
|
|
|
71
72
|
p(r, s);
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
|
-
function
|
|
75
|
+
function T(r, o) {
|
|
75
76
|
if (typeof OffscreenCanvas < "u")
|
|
76
77
|
return new OffscreenCanvas(r, o);
|
|
77
78
|
const c = document.createElement("canvas");
|
|
78
79
|
return c.width = r, c.height = o, c;
|
|
79
80
|
}
|
|
80
|
-
function
|
|
81
|
+
function v(r, o) {
|
|
81
82
|
var e;
|
|
82
|
-
const c = o.opacity ?? 1,
|
|
83
|
-
c < 1 &&
|
|
83
|
+
const c = o.opacity ?? 1, a = !!((e = o.stroke) != null && e.enabled);
|
|
84
|
+
c < 1 && a ? k(r, o, c) : g(r, o, c);
|
|
84
85
|
}
|
|
85
|
-
function
|
|
86
|
+
function k(r, o, c) {
|
|
86
87
|
var f;
|
|
87
|
-
const
|
|
88
|
+
const a = o.transformData, e = (((f = o.stroke) == null ? void 0 : f.width) || 2) + 2, n = Math.ceil(a.width + e * 2), i = Math.ceil(a.height + e * 2), s = T(n, i), t = s.getContext("2d");
|
|
88
89
|
if (!t) {
|
|
89
90
|
g(r, o, c);
|
|
90
91
|
return;
|
|
@@ -92,138 +93,138 @@ function T(r, o, c) {
|
|
|
92
93
|
const d = {
|
|
93
94
|
...o,
|
|
94
95
|
x: n / 2,
|
|
95
|
-
y:
|
|
96
|
+
y: i / 2
|
|
96
97
|
};
|
|
97
|
-
g(t, d, 1), r.save(), r.translate(o.x, o.y), o.rotation && r.rotate(-o.rotation * Math.PI / 180), r.globalAlpha = c, r.drawImage(s, -n / 2, -
|
|
98
|
+
g(t, d, 1), r.save(), r.translate(o.x, o.y), o.rotation && r.rotate(-o.rotation * Math.PI / 180), r.globalAlpha = c, r.drawImage(s, -n / 2, -i / 2), r.restore();
|
|
98
99
|
}
|
|
99
100
|
function g(r, o, c) {
|
|
100
101
|
var e;
|
|
101
|
-
const
|
|
102
|
-
if (r.save(), r.translate(o.x, o.y), o.rotation && r.rotate(-o.rotation * Math.PI / 180), r.globalAlpha = c * h, r.fillStyle =
|
|
102
|
+
const a = o.transformData, h = a.fillOpacity ?? 1;
|
|
103
|
+
if (r.save(), r.translate(o.x, o.y), o.rotation && r.rotate(-o.rotation * Math.PI / 180), r.globalAlpha = c * h, r.fillStyle = a.fillColor || "#3b82f6", r.beginPath(), u(r, a), r.fill(), r.restore(), (e = o.stroke) != null && e.enabled) {
|
|
103
104
|
r.save(), r.translate(o.x, o.y), o.rotation && r.rotate(-o.rotation * Math.PI / 180);
|
|
104
105
|
const n = o.stroke;
|
|
105
|
-
r.globalAlpha = c * (n.opacity ?? 1), r.strokeStyle = n.color || "#000000", r.lineWidth = n.width || 2, r.lineCap = n.lineCap || "round", r.lineJoin = n.lineJoin || "round", r.beginPath(), u(r,
|
|
106
|
+
r.globalAlpha = c * (n.opacity ?? 1), r.strokeStyle = n.color || "#000000", r.lineWidth = n.width || 2, r.lineCap = n.lineCap || "round", r.lineJoin = n.lineJoin || "round", r.beginPath(), u(r, a), r.stroke(), r.restore();
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
function u(r, o) {
|
|
109
|
-
const { shapeType: c, width:
|
|
110
|
+
const { shapeType: c, width: a, height: h } = o;
|
|
110
111
|
switch (c) {
|
|
111
112
|
case "rectangle": {
|
|
112
|
-
const e = o.borderRadius || 0, n = -
|
|
113
|
+
const e = o.borderRadius || 0, n = -a / 2, i = -h / 2;
|
|
113
114
|
if (e > 0) {
|
|
114
|
-
const s = Math.min(e / 100 * Math.min(
|
|
115
|
-
r.roundRect(n,
|
|
115
|
+
const s = Math.min(e / 100 * Math.min(a, h), a / 2, h / 2);
|
|
116
|
+
r.roundRect(n, i, a, h, s);
|
|
116
117
|
} else
|
|
117
|
-
r.rect(n,
|
|
118
|
+
r.rect(n, i, a, h);
|
|
118
119
|
break;
|
|
119
120
|
}
|
|
120
121
|
case "circle": {
|
|
121
|
-
const e = Math.min(
|
|
122
|
+
const e = Math.min(a, h) / 2;
|
|
122
123
|
r.arc(0, 0, e, 0, Math.PI * 2);
|
|
123
124
|
break;
|
|
124
125
|
}
|
|
125
126
|
case "ellipse": {
|
|
126
|
-
r.ellipse(0, 0,
|
|
127
|
+
r.ellipse(0, 0, a / 2, h / 2, 0, 0, Math.PI * 2);
|
|
127
128
|
break;
|
|
128
129
|
}
|
|
129
130
|
case "triangle": {
|
|
130
|
-
const e =
|
|
131
|
+
const e = a / 2, n = h / 2;
|
|
131
132
|
r.moveTo(0, -n), r.lineTo(e, n), r.lineTo(-e, n), r.closePath();
|
|
132
133
|
break;
|
|
133
134
|
}
|
|
134
135
|
case "polygon": {
|
|
135
|
-
const e = o.sides || 5, n = Math.min(
|
|
136
|
-
for (let
|
|
137
|
-
const s =
|
|
138
|
-
|
|
136
|
+
const e = o.sides || 5, n = Math.min(a, h) / 2;
|
|
137
|
+
for (let i = 0; i < e; i++) {
|
|
138
|
+
const s = i * 2 * Math.PI / e - Math.PI / 2, t = n * Math.cos(s), d = n * Math.sin(s);
|
|
139
|
+
i === 0 ? r.moveTo(t, d) : r.lineTo(t, d);
|
|
139
140
|
}
|
|
140
141
|
r.closePath();
|
|
141
142
|
break;
|
|
142
143
|
}
|
|
143
144
|
case "star": {
|
|
144
|
-
const e = o.points || 5, n = Math.min(
|
|
145
|
+
const e = o.points || 5, n = Math.min(a, h) / 2, i = n * (o.innerRadius || 0.4);
|
|
145
146
|
for (let s = 0; s < e * 2; s++) {
|
|
146
|
-
const t = s * Math.PI / e - Math.PI / 2, d = s % 2 === 0 ? n :
|
|
147
|
+
const t = s * Math.PI / e - Math.PI / 2, d = s % 2 === 0 ? n : i, f = d * Math.cos(t), l = d * Math.sin(t);
|
|
147
148
|
s === 0 ? r.moveTo(f, l) : r.lineTo(f, l);
|
|
148
149
|
}
|
|
149
150
|
r.closePath();
|
|
150
151
|
break;
|
|
151
152
|
}
|
|
152
153
|
case "line": {
|
|
153
|
-
const e =
|
|
154
|
-
r.rect(-e, -n,
|
|
154
|
+
const e = a / 2, n = h / 2;
|
|
155
|
+
r.rect(-e, -n, a, h);
|
|
155
156
|
break;
|
|
156
157
|
}
|
|
157
158
|
default:
|
|
158
|
-
r.rect(-
|
|
159
|
+
r.rect(-a / 2, -h / 2, a, h);
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
export {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
163
|
+
b as AlignmentSnapSystem,
|
|
164
|
+
Hr as AnyElementConfigSchema,
|
|
165
|
+
Or as AnyTransformDataSchema,
|
|
166
|
+
F as ArchTransform,
|
|
167
|
+
L as ArtboardManager,
|
|
168
|
+
w as ArtboardRenderer,
|
|
169
|
+
X as AscendTransform,
|
|
169
170
|
I as CanvasRenderer,
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
171
|
+
Fr as CanvasStateV1Schema,
|
|
172
|
+
K as CircleTransform,
|
|
173
|
+
Y as CustomTransform,
|
|
174
|
+
kr as DEFAULT_MAX_BITMAP_DIMENSION,
|
|
175
|
+
z as ElementStore,
|
|
176
|
+
Mr as ExportManager,
|
|
177
|
+
_ as FlagTransform,
|
|
178
|
+
B as HybridHistoryManager,
|
|
179
|
+
R as ImportManager,
|
|
180
|
+
W as InteractionStateMachine,
|
|
181
|
+
J as LeanTransform,
|
|
182
|
+
N as LogLevel,
|
|
183
|
+
A as ResizePipeline,
|
|
184
|
+
Lr as SerializedArtboardSchema,
|
|
185
|
+
E as SpacingSystem,
|
|
186
|
+
H as TransformHandles,
|
|
187
|
+
V as WaveTransform,
|
|
188
|
+
yr as WorkerExportManager,
|
|
189
|
+
U as applySpaceLayoutRules,
|
|
190
|
+
Q as applyStrokeStyle,
|
|
191
|
+
Z as buildFontString,
|
|
192
|
+
$ as calculateFixedCornerPosition,
|
|
193
|
+
j as calculateResizeHandles,
|
|
194
|
+
q as calculateRotationHandlePosition,
|
|
195
|
+
Cr as clearImageBitmapCache,
|
|
196
|
+
vr as clearMaskCache,
|
|
197
|
+
Sr as clearRegisteredBitmapKeys,
|
|
198
|
+
G as createCirclePath,
|
|
199
|
+
m as createImagePath,
|
|
200
|
+
x as createLogger,
|
|
201
|
+
D as createRectPath,
|
|
202
|
+
rr as createTextPath,
|
|
203
|
+
or as getFontMetrics,
|
|
204
|
+
Pr as getSharedWorkerExportManager,
|
|
205
|
+
sr as hitTestCircle,
|
|
206
|
+
ir as hitTestRect,
|
|
207
|
+
br as invalidateMaskCache,
|
|
208
|
+
ar as logger,
|
|
209
|
+
er as measureTextWidth,
|
|
210
|
+
wr as removeFromImageBitmapCache,
|
|
211
|
+
nr as renderCustomTransform,
|
|
212
|
+
C as renderImageElement,
|
|
212
213
|
p as renderImageStroke,
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
214
|
+
tr as renderMultilineText,
|
|
215
|
+
hr as renderPathStroke,
|
|
216
|
+
dr as renderRichTextFillOnly,
|
|
217
|
+
v as renderShapeElement,
|
|
218
|
+
cr as renderTextElement,
|
|
219
|
+
fr as renderTextFillOnly,
|
|
220
|
+
pr as renderTextStroke,
|
|
221
|
+
Ir as renderWithKnockout,
|
|
222
|
+
Rr as renderWithMasks,
|
|
223
|
+
y as resolveServerCrop,
|
|
224
|
+
gr as splitRichTextIntoLines,
|
|
225
|
+
Wr as terminateSharedWorkerExportManager,
|
|
226
|
+
Ar as unregisterElementBitmaps,
|
|
227
|
+
lr as wrapRichTextSpans,
|
|
228
|
+
ur as wrapText
|
|
228
229
|
};
|
|
229
230
|
//# sourceMappingURL=internals.mjs.map
|
package/dist/internals.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internals.mjs","sources":["../src/rendering/image-renderer.ts","../src/rendering/shape-renderer.ts"],"sourcesContent":["/**\n * Image Renderer - Image element rendering with crop, flip, border radius, and stroke.\n *\n * Works in both main thread and Web Worker (via OffscreenCanvas).\n */\n\nimport type { ImageElementConfig } from '../types/index.js';\nimport { renderImageStroke } from './StrokeRenderer.js';\nimport type { RenderContext, SerializedImageElement } from './renderer-types.js';\n\n/**\n * Convert a server-render image element's crop rectangle from FRACTIONS (0–1)\n * to source pixels, using the fetched bitmap's real dimensions.\n *\n * The server-render serializers (`serializeStateForServer`,\n * `flattenImageElement`) store crop as fractions and stamp\n * `needsCropPixelConversion` because they have no bitmap at serialize time. The\n * export worker holds the bitmap and calls this right before drawing. Without\n * it, `drawImage` reads e.g. `cropWidth=1` as a 1px source rect and stretches a\n * single corner pixel across the whole element — the layer renders as a solid\n * black/transparent block. Mirrors the client-side conversion in\n * `element-serializer` (which runs at serialize time because the client DOES\n * have the bitmap). No-op unless the flag is set and a crop is present, so the\n * already-pixel client path is untouched and the conversion can't run twice.\n */\nexport function resolveServerCrop(\n el: SerializedImageElement,\n bitmap: { width: number; height: number }\n): SerializedImageElement {\n if (!el.needsCropPixelConversion || el.cropWidth === undefined) return el;\n return {\n ...el,\n cropX: (el.cropX ?? 0) * bitmap.width,\n cropY: (el.cropY ?? 0) * bitmap.height,\n cropWidth: el.cropWidth * bitmap.width,\n cropHeight: (el.cropHeight ?? 1) * bitmap.height,\n needsCropPixelConversion: false,\n };\n}\n\n/**\n * Render an image element using ImageBitmap\n * Works in both main thread and worker\n */\nexport function renderImageElement(\n ctx: RenderContext,\n elementData: SerializedImageElement,\n imageBitmap: ImageBitmap\n): void {\n ctx.save();\n\n // Translate to element position\n ctx.translate(elementData.x, elementData.y);\n\n // Apply rotation (negative for clockwise)\n if (elementData.rotation) {\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n }\n\n // Apply flip transformations\n let scaleX = 1;\n let scaleY = 1;\n if (elementData.flipHorizontal) scaleX = -1;\n if (elementData.flipVertical) scaleY = -1;\n if (scaleX !== 1 || scaleY !== 1) {\n ctx.scale(scaleX, scaleY);\n }\n\n // Apply opacity if specified\n if (elementData.opacity !== undefined && elementData.opacity !== 1) {\n ctx.globalAlpha = elementData.opacity;\n }\n\n // Apply border radius if specified (borderRadius is stored as percentage 0-100)\n if (elementData.borderRadius && elementData.borderRadius > 0) {\n const radius = Math.min(\n (elementData.borderRadius / 100) * Math.min(elementData.width, elementData.height),\n elementData.width / 2,\n elementData.height / 2\n );\n\n // Create clipping path for rounded corners\n ctx.beginPath();\n const x = -elementData.width / 2;\n const y = -elementData.height / 2;\n const w = elementData.width;\n const h = elementData.height;\n\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + w - radius, y);\n ctx.arcTo(x + w, y, x + w, y + radius, radius);\n ctx.lineTo(x + w, y + h - radius);\n ctx.arcTo(x + w, y + h, x + w - radius, y + h, radius);\n ctx.lineTo(x + radius, y + h);\n ctx.arcTo(x, y + h, x, y + h - radius, radius);\n ctx.lineTo(x, y + radius);\n ctx.arcTo(x, y, x + radius, y, radius);\n ctx.closePath();\n ctx.clip();\n }\n\n // Draw the image\n if (elementData.cropX !== undefined && elementData.cropWidth !== undefined) {\n // Draw with crop\n ctx.drawImage(\n imageBitmap,\n elementData.cropX,\n elementData.cropY || 0,\n elementData.cropWidth,\n elementData.cropHeight || imageBitmap.height,\n -elementData.width / 2,\n -elementData.height / 2,\n elementData.width,\n elementData.height\n );\n } else {\n // Draw without crop (centered)\n ctx.drawImage(imageBitmap, -elementData.width / 2, -elementData.height / 2, elementData.width, elementData.height);\n }\n\n ctx.restore();\n\n // Render stroke if enabled (after restore to apply fresh transforms)\n if (elementData.stroke?.enabled) {\n const hasKnockoutStroke = elementData.knockoutParts?.stroke === true;\n\n const imageConfig: ImageElementConfig = {\n transformType: 'image',\n x: elementData.x,\n y: elementData.y,\n rotation: elementData.rotation,\n stroke: elementData.stroke,\n knockoutParts: elementData.knockoutParts,\n transformData: {\n type: 'image',\n width: elementData.width,\n height: elementData.height,\n borderRadius: elementData.borderRadius || 0,\n },\n };\n\n if (hasKnockoutStroke) {\n // For knockout stroke, use offscreen canvas approach\n const canvas = ctx.canvas;\n let offscreen: HTMLCanvasElement | OffscreenCanvas;\n\n if (typeof OffscreenCanvas !== 'undefined') {\n offscreen = new OffscreenCanvas(canvas.width, canvas.height);\n } else if (typeof document !== 'undefined') {\n offscreen = document.createElement('canvas');\n offscreen.width = canvas.width;\n offscreen.height = canvas.height;\n } else {\n renderImageStroke(ctx, imageConfig);\n return;\n }\n\n const offCtx = offscreen.getContext('2d');\n if (!offCtx) {\n renderImageStroke(ctx, imageConfig);\n return;\n }\n\n // Render the stroke to the offscreen canvas with knockout flag\n renderImageStroke(offCtx, imageConfig, { isKnockout: true });\n\n // Composite with destination-out\n ctx.save();\n ctx.globalCompositeOperation = 'destination-out';\n ctx.drawImage(offscreen as CanvasImageSource, 0, 0);\n ctx.restore();\n } else {\n // Normal stroke\n renderImageStroke(ctx, imageConfig);\n }\n }\n}\n","/**\n * Shape Renderer - Shape element rendering (rectangle, circle, ellipse, triangle, etc.)\n *\n * Works in both main thread and Web Worker (via OffscreenCanvas).\n *\n * Opacity strategy: When a shape has both element-level opacity AND a stroke,\n * we render fill+stroke at full opacity on a temporary canvas, then composite\n * the result at the element's opacity. This prevents fill/stroke overlap from\n * compounding (e.g., 50% fill + 50% stroke overlap ≠ 75% opaque).\n */\n\nimport type { RenderContext, SerializedShapeElement } from './renderer-types.js';\n\ntype CanvasLike = HTMLCanvasElement | OffscreenCanvas;\n\nfunction createTempCanvas(width: number, height: number): CanvasLike {\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(width, height);\n }\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n}\n\n/**\n * Render a shape element\n * Works in both main thread and worker\n */\nexport function renderShapeElement(ctx: RenderContext, elementData: SerializedShapeElement): void {\n const elementOpacity = elementData.opacity ?? 1;\n const hasStroke = !!elementData.stroke?.enabled;\n const needsOffscreen = elementOpacity < 1 && hasStroke;\n\n if (needsOffscreen) {\n // Render fill+stroke at full opacity on a temp canvas, then composite\n renderShapeWithOffscreen(ctx, elementData, elementOpacity);\n } else {\n // No compounding risk — render directly\n renderShapeDirect(ctx, elementData, elementOpacity);\n }\n}\n\n/**\n * Render shape via temporary canvas to avoid fill/stroke opacity compounding.\n */\nfunction renderShapeWithOffscreen(\n ctx: RenderContext,\n elementData: SerializedShapeElement,\n elementOpacity: number\n): void {\n const td = elementData.transformData;\n const strokeWidth = elementData.stroke?.width || 2;\n // Pad temp canvas to fit the stroke (strokes extend beyond the shape bounds)\n const padding = strokeWidth + 2;\n const offW = Math.ceil(td.width + padding * 2);\n const offH = Math.ceil(td.height + padding * 2);\n\n const offCanvas = createTempCanvas(offW, offH);\n const offCtx = offCanvas.getContext('2d') as RenderContext;\n if (!offCtx) {\n // Fallback to direct render\n renderShapeDirect(ctx, elementData, elementOpacity);\n return;\n }\n\n // Render at center of temp canvas with full opacity (elementOpacity = 1)\n const tempData: SerializedShapeElement = {\n ...elementData,\n x: offW / 2,\n y: offH / 2,\n opacity: 1,\n };\n renderShapeDirect(offCtx, tempData, 1);\n\n // Composite temp canvas onto main canvas at element opacity\n ctx.save();\n\n // Position: elementData.(x,y) is the shape center, temp canvas center is (offW/2, offH/2)\n // We need to account for rotation around the element center\n ctx.translate(elementData.x, elementData.y);\n if (elementData.rotation) {\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n }\n\n ctx.globalAlpha = elementOpacity;\n ctx.drawImage(offCanvas, -offW / 2, -offH / 2);\n ctx.restore();\n}\n\n/**\n * Render shape directly onto ctx (no offscreen). Used when there's no\n * compounding risk, or as the inner render for the offscreen path.\n */\nfunction renderShapeDirect(\n ctx: RenderContext,\n elementData: SerializedShapeElement,\n elementOpacity: number\n): void {\n const transformData = elementData.transformData;\n const fillOpacity = transformData.fillOpacity ?? 1;\n\n ctx.save();\n ctx.translate(elementData.x, elementData.y);\n\n if (elementData.rotation) {\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n }\n\n // Fill\n ctx.globalAlpha = elementOpacity * fillOpacity;\n ctx.fillStyle = transformData.fillColor || '#3b82f6';\n ctx.beginPath();\n traceShapePath(ctx, transformData);\n ctx.fill();\n ctx.restore();\n\n // Stroke\n if (elementData.stroke?.enabled) {\n ctx.save();\n ctx.translate(elementData.x, elementData.y);\n if (elementData.rotation) {\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n }\n\n const stroke = elementData.stroke;\n ctx.globalAlpha = elementOpacity * (stroke.opacity ?? 1);\n ctx.strokeStyle = stroke.color || '#000000';\n ctx.lineWidth = stroke.width || 2;\n ctx.lineCap = stroke.lineCap || 'round';\n ctx.lineJoin = stroke.lineJoin || 'round';\n\n ctx.beginPath();\n traceShapePath(ctx, transformData);\n ctx.stroke();\n ctx.restore();\n }\n}\n\n/**\n * Trace the shape path (without fill/stroke) — reusable for both fill and stroke passes.\n */\nfunction traceShapePath(\n ctx: RenderContext,\n transformData: SerializedShapeElement['transformData']\n): void {\n const { shapeType, width, height } = transformData;\n\n switch (shapeType) {\n case 'rectangle': {\n const borderRadius = transformData.borderRadius || 0;\n const x = -width / 2;\n const y = -height / 2;\n\n if (borderRadius > 0) {\n const radius = Math.min((borderRadius / 100) * Math.min(width, height), width / 2, height / 2);\n ctx.roundRect(x, y, width, height, radius);\n } else {\n ctx.rect(x, y, width, height);\n }\n break;\n }\n\n case 'circle': {\n const radius = Math.min(width, height) / 2;\n ctx.arc(0, 0, radius, 0, Math.PI * 2);\n break;\n }\n\n case 'ellipse': {\n ctx.ellipse(0, 0, width / 2, height / 2, 0, 0, Math.PI * 2);\n break;\n }\n\n case 'triangle': {\n const halfWidth = width / 2;\n const halfHeight = height / 2;\n ctx.moveTo(0, -halfHeight);\n ctx.lineTo(halfWidth, halfHeight);\n ctx.lineTo(-halfWidth, halfHeight);\n ctx.closePath();\n break;\n }\n\n case 'polygon': {\n const sides = transformData.sides || 5;\n const radius = Math.min(width, height) / 2;\n for (let i = 0; i < sides; i++) {\n const angle = (i * 2 * Math.PI) / sides - Math.PI / 2;\n const px = radius * Math.cos(angle);\n const py = radius * Math.sin(angle);\n if (i === 0) {\n ctx.moveTo(px, py);\n } else {\n ctx.lineTo(px, py);\n }\n }\n ctx.closePath();\n break;\n }\n\n case 'star': {\n const points = transformData.points || 5;\n const outerRadius = Math.min(width, height) / 2;\n const innerRadius = outerRadius * (transformData.innerRadius || 0.4);\n for (let i = 0; i < points * 2; i++) {\n const angle = (i * Math.PI) / points - Math.PI / 2;\n const r = i % 2 === 0 ? outerRadius : innerRadius;\n const px = r * Math.cos(angle);\n const py = r * Math.sin(angle);\n if (i === 0) {\n ctx.moveTo(px, py);\n } else {\n ctx.lineTo(px, py);\n }\n }\n ctx.closePath();\n break;\n }\n\n case 'line': {\n const halfWidth = width / 2;\n const halfHeight = height / 2;\n ctx.rect(-halfWidth, -halfHeight, width, height);\n break;\n }\n\n default:\n ctx.rect(-width / 2, -height / 2, width, height);\n }\n}\n"],"names":["resolveServerCrop","el","bitmap","renderImageElement","ctx","elementData","imageBitmap","scaleX","scaleY","radius","x","y","w","h","_a","hasKnockoutStroke","_b","imageConfig","canvas","offscreen","renderImageStroke","offCtx","createTempCanvas","width","height","renderShapeElement","elementOpacity","hasStroke","renderShapeWithOffscreen","renderShapeDirect","td","padding","offW","offH","offCanvas","tempData","transformData","fillOpacity","traceShapePath","stroke","shapeType","borderRadius","halfWidth","halfHeight","sides","i","angle","px","py","points","outerRadius","innerRadius","r"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"internals.mjs","sources":["../src/rendering/image-renderer.ts","../src/rendering/shape-renderer.ts"],"sourcesContent":["/**\n * Image Renderer - Image element rendering with crop, flip, border radius, and stroke.\n *\n * Works in both main thread and Web Worker (via OffscreenCanvas).\n */\n\nimport type { ImageElementConfig } from '../types/index.js';\nimport { renderImageStroke } from './StrokeRenderer.js';\nimport type { RenderContext, SerializedImageElement } from './renderer-types.js';\n\n/**\n * Convert a server-render image element's crop rectangle from FRACTIONS (0–1)\n * to source pixels, using the fetched bitmap's real dimensions.\n *\n * The server-render serializers (`serializeStateForServer`,\n * `flattenImageElement`) store crop as fractions and stamp\n * `needsCropPixelConversion` because they have no bitmap at serialize time. The\n * export worker holds the bitmap and calls this right before drawing. Without\n * it, `drawImage` reads e.g. `cropWidth=1` as a 1px source rect and stretches a\n * single corner pixel across the whole element — the layer renders as a solid\n * black/transparent block. Mirrors the client-side conversion in\n * `element-serializer` (which runs at serialize time because the client DOES\n * have the bitmap). No-op unless the flag is set and a crop is present, so the\n * already-pixel client path is untouched and the conversion can't run twice.\n */\nexport function resolveServerCrop(\n el: SerializedImageElement,\n bitmap: { width: number; height: number }\n): SerializedImageElement {\n if (!el.needsCropPixelConversion || el.cropWidth === undefined) return el;\n return {\n ...el,\n cropX: (el.cropX ?? 0) * bitmap.width,\n cropY: (el.cropY ?? 0) * bitmap.height,\n cropWidth: el.cropWidth * bitmap.width,\n cropHeight: (el.cropHeight ?? 1) * bitmap.height,\n needsCropPixelConversion: false,\n };\n}\n\n/**\n * Render an image element using ImageBitmap\n * Works in both main thread and worker\n */\nexport function renderImageElement(\n ctx: RenderContext,\n elementData: SerializedImageElement,\n imageBitmap: ImageBitmap\n): void {\n ctx.save();\n\n // Translate to element position\n ctx.translate(elementData.x, elementData.y);\n\n // Apply rotation (negative for clockwise)\n if (elementData.rotation) {\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n }\n\n // Apply flip transformations\n let scaleX = 1;\n let scaleY = 1;\n if (elementData.flipHorizontal) scaleX = -1;\n if (elementData.flipVertical) scaleY = -1;\n if (scaleX !== 1 || scaleY !== 1) {\n ctx.scale(scaleX, scaleY);\n }\n\n // Apply opacity if specified\n if (elementData.opacity !== undefined && elementData.opacity !== 1) {\n ctx.globalAlpha = elementData.opacity;\n }\n\n // Apply border radius if specified (borderRadius is stored as percentage 0-100)\n if (elementData.borderRadius && elementData.borderRadius > 0) {\n const radius = Math.min(\n (elementData.borderRadius / 100) * Math.min(elementData.width, elementData.height),\n elementData.width / 2,\n elementData.height / 2\n );\n\n // Create clipping path for rounded corners\n ctx.beginPath();\n const x = -elementData.width / 2;\n const y = -elementData.height / 2;\n const w = elementData.width;\n const h = elementData.height;\n\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + w - radius, y);\n ctx.arcTo(x + w, y, x + w, y + radius, radius);\n ctx.lineTo(x + w, y + h - radius);\n ctx.arcTo(x + w, y + h, x + w - radius, y + h, radius);\n ctx.lineTo(x + radius, y + h);\n ctx.arcTo(x, y + h, x, y + h - radius, radius);\n ctx.lineTo(x, y + radius);\n ctx.arcTo(x, y, x + radius, y, radius);\n ctx.closePath();\n ctx.clip();\n }\n\n // Draw the image\n if (elementData.cropX !== undefined && elementData.cropWidth !== undefined) {\n // Draw with crop\n ctx.drawImage(\n imageBitmap,\n elementData.cropX,\n elementData.cropY || 0,\n elementData.cropWidth,\n elementData.cropHeight || imageBitmap.height,\n -elementData.width / 2,\n -elementData.height / 2,\n elementData.width,\n elementData.height\n );\n } else {\n // Draw without crop (centered)\n ctx.drawImage(imageBitmap, -elementData.width / 2, -elementData.height / 2, elementData.width, elementData.height);\n }\n\n ctx.restore();\n\n // Render stroke if enabled (after restore to apply fresh transforms)\n if (elementData.stroke?.enabled) {\n const hasKnockoutStroke = elementData.knockoutParts?.stroke === true;\n\n const imageConfig: ImageElementConfig = {\n transformType: 'image',\n x: elementData.x,\n y: elementData.y,\n rotation: elementData.rotation,\n stroke: elementData.stroke,\n knockoutParts: elementData.knockoutParts,\n transformData: {\n type: 'image',\n width: elementData.width,\n height: elementData.height,\n borderRadius: elementData.borderRadius || 0,\n },\n };\n\n if (hasKnockoutStroke) {\n // For knockout stroke, use offscreen canvas approach\n const canvas = ctx.canvas;\n let offscreen: HTMLCanvasElement | OffscreenCanvas;\n\n if (typeof OffscreenCanvas !== 'undefined') {\n offscreen = new OffscreenCanvas(canvas.width, canvas.height);\n } else if (typeof document !== 'undefined') {\n offscreen = document.createElement('canvas');\n offscreen.width = canvas.width;\n offscreen.height = canvas.height;\n } else {\n renderImageStroke(ctx, imageConfig);\n return;\n }\n\n const offCtx = offscreen.getContext('2d');\n if (!offCtx) {\n renderImageStroke(ctx, imageConfig);\n return;\n }\n\n // Render the stroke to the offscreen canvas with knockout flag\n renderImageStroke(offCtx, imageConfig, { isKnockout: true });\n\n // Composite with destination-out\n ctx.save();\n ctx.globalCompositeOperation = 'destination-out';\n ctx.drawImage(offscreen as CanvasImageSource, 0, 0);\n ctx.restore();\n } else {\n // Normal stroke\n renderImageStroke(ctx, imageConfig);\n }\n }\n}\n","/**\n * Shape Renderer - Shape element rendering (rectangle, circle, ellipse, triangle, etc.)\n *\n * Works in both main thread and Web Worker (via OffscreenCanvas).\n *\n * Opacity strategy: When a shape has both element-level opacity AND a stroke,\n * we render fill+stroke at full opacity on a temporary canvas, then composite\n * the result at the element's opacity. This prevents fill/stroke overlap from\n * compounding (e.g., 50% fill + 50% stroke overlap ≠ 75% opaque).\n */\n\nimport type { RenderContext, SerializedShapeElement } from './renderer-types.js';\n\ntype CanvasLike = HTMLCanvasElement | OffscreenCanvas;\n\nfunction createTempCanvas(width: number, height: number): CanvasLike {\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(width, height);\n }\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n}\n\n/**\n * Render a shape element\n * Works in both main thread and worker\n */\nexport function renderShapeElement(ctx: RenderContext, elementData: SerializedShapeElement): void {\n const elementOpacity = elementData.opacity ?? 1;\n const hasStroke = !!elementData.stroke?.enabled;\n const needsOffscreen = elementOpacity < 1 && hasStroke;\n\n if (needsOffscreen) {\n // Render fill+stroke at full opacity on a temp canvas, then composite\n renderShapeWithOffscreen(ctx, elementData, elementOpacity);\n } else {\n // No compounding risk — render directly\n renderShapeDirect(ctx, elementData, elementOpacity);\n }\n}\n\n/**\n * Render shape via temporary canvas to avoid fill/stroke opacity compounding.\n */\nfunction renderShapeWithOffscreen(\n ctx: RenderContext,\n elementData: SerializedShapeElement,\n elementOpacity: number\n): void {\n const td = elementData.transformData;\n const strokeWidth = elementData.stroke?.width || 2;\n // Pad temp canvas to fit the stroke (strokes extend beyond the shape bounds)\n const padding = strokeWidth + 2;\n const offW = Math.ceil(td.width + padding * 2);\n const offH = Math.ceil(td.height + padding * 2);\n\n const offCanvas = createTempCanvas(offW, offH);\n const offCtx = offCanvas.getContext('2d') as RenderContext;\n if (!offCtx) {\n // Fallback to direct render\n renderShapeDirect(ctx, elementData, elementOpacity);\n return;\n }\n\n // Render at center of temp canvas with full opacity (elementOpacity = 1)\n const tempData: SerializedShapeElement = {\n ...elementData,\n x: offW / 2,\n y: offH / 2,\n opacity: 1,\n };\n renderShapeDirect(offCtx, tempData, 1);\n\n // Composite temp canvas onto main canvas at element opacity\n ctx.save();\n\n // Position: elementData.(x,y) is the shape center, temp canvas center is (offW/2, offH/2)\n // We need to account for rotation around the element center\n ctx.translate(elementData.x, elementData.y);\n if (elementData.rotation) {\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n }\n\n ctx.globalAlpha = elementOpacity;\n ctx.drawImage(offCanvas, -offW / 2, -offH / 2);\n ctx.restore();\n}\n\n/**\n * Render shape directly onto ctx (no offscreen). Used when there's no\n * compounding risk, or as the inner render for the offscreen path.\n */\nfunction renderShapeDirect(\n ctx: RenderContext,\n elementData: SerializedShapeElement,\n elementOpacity: number\n): void {\n const transformData = elementData.transformData;\n const fillOpacity = transformData.fillOpacity ?? 1;\n\n ctx.save();\n ctx.translate(elementData.x, elementData.y);\n\n if (elementData.rotation) {\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n }\n\n // Fill\n ctx.globalAlpha = elementOpacity * fillOpacity;\n ctx.fillStyle = transformData.fillColor || '#3b82f6';\n ctx.beginPath();\n traceShapePath(ctx, transformData);\n ctx.fill();\n ctx.restore();\n\n // Stroke\n if (elementData.stroke?.enabled) {\n ctx.save();\n ctx.translate(elementData.x, elementData.y);\n if (elementData.rotation) {\n ctx.rotate((-elementData.rotation * Math.PI) / 180);\n }\n\n const stroke = elementData.stroke;\n ctx.globalAlpha = elementOpacity * (stroke.opacity ?? 1);\n ctx.strokeStyle = stroke.color || '#000000';\n ctx.lineWidth = stroke.width || 2;\n ctx.lineCap = stroke.lineCap || 'round';\n ctx.lineJoin = stroke.lineJoin || 'round';\n\n ctx.beginPath();\n traceShapePath(ctx, transformData);\n ctx.stroke();\n ctx.restore();\n }\n}\n\n/**\n * Trace the shape path (without fill/stroke) — reusable for both fill and stroke passes.\n */\nfunction traceShapePath(\n ctx: RenderContext,\n transformData: SerializedShapeElement['transformData']\n): void {\n const { shapeType, width, height } = transformData;\n\n switch (shapeType) {\n case 'rectangle': {\n const borderRadius = transformData.borderRadius || 0;\n const x = -width / 2;\n const y = -height / 2;\n\n if (borderRadius > 0) {\n const radius = Math.min((borderRadius / 100) * Math.min(width, height), width / 2, height / 2);\n ctx.roundRect(x, y, width, height, radius);\n } else {\n ctx.rect(x, y, width, height);\n }\n break;\n }\n\n case 'circle': {\n const radius = Math.min(width, height) / 2;\n ctx.arc(0, 0, radius, 0, Math.PI * 2);\n break;\n }\n\n case 'ellipse': {\n ctx.ellipse(0, 0, width / 2, height / 2, 0, 0, Math.PI * 2);\n break;\n }\n\n case 'triangle': {\n const halfWidth = width / 2;\n const halfHeight = height / 2;\n ctx.moveTo(0, -halfHeight);\n ctx.lineTo(halfWidth, halfHeight);\n ctx.lineTo(-halfWidth, halfHeight);\n ctx.closePath();\n break;\n }\n\n case 'polygon': {\n const sides = transformData.sides || 5;\n const radius = Math.min(width, height) / 2;\n for (let i = 0; i < sides; i++) {\n const angle = (i * 2 * Math.PI) / sides - Math.PI / 2;\n const px = radius * Math.cos(angle);\n const py = radius * Math.sin(angle);\n if (i === 0) {\n ctx.moveTo(px, py);\n } else {\n ctx.lineTo(px, py);\n }\n }\n ctx.closePath();\n break;\n }\n\n case 'star': {\n const points = transformData.points || 5;\n const outerRadius = Math.min(width, height) / 2;\n const innerRadius = outerRadius * (transformData.innerRadius || 0.4);\n for (let i = 0; i < points * 2; i++) {\n const angle = (i * Math.PI) / points - Math.PI / 2;\n const r = i % 2 === 0 ? outerRadius : innerRadius;\n const px = r * Math.cos(angle);\n const py = r * Math.sin(angle);\n if (i === 0) {\n ctx.moveTo(px, py);\n } else {\n ctx.lineTo(px, py);\n }\n }\n ctx.closePath();\n break;\n }\n\n case 'line': {\n const halfWidth = width / 2;\n const halfHeight = height / 2;\n ctx.rect(-halfWidth, -halfHeight, width, height);\n break;\n }\n\n default:\n ctx.rect(-width / 2, -height / 2, width, height);\n }\n}\n"],"names":["resolveServerCrop","el","bitmap","renderImageElement","ctx","elementData","imageBitmap","scaleX","scaleY","radius","x","y","w","h","_a","hasKnockoutStroke","_b","imageConfig","canvas","offscreen","renderImageStroke","offCtx","createTempCanvas","width","height","renderShapeElement","elementOpacity","hasStroke","renderShapeWithOffscreen","renderShapeDirect","td","padding","offW","offH","offCanvas","tempData","transformData","fillOpacity","traceShapePath","stroke","shapeType","borderRadius","halfWidth","halfHeight","sides","angle","px","py","points","outerRadius","innerRadius","i","r"],"mappings":"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"}
|