@umituz/web-canvas 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/application/index.d.mts +1 -1
- package/dist/application/index.d.ts +1 -1
- package/dist/application/index.js +103 -40
- package/dist/application/index.mjs +2 -2
- package/dist/{chunk-BN7JTXL7.mjs → chunk-DNKRSL6D.mjs} +24 -12
- package/dist/{chunk-SF6WND7M.mjs → chunk-LOVI2LTO.mjs} +88 -28
- package/dist/{chunk-WMKPCJFI.mjs → chunk-UOGTEMIJ.mjs} +80 -29
- package/dist/index.js +186 -63
- package/dist/index.mjs +3 -3
- package/dist/infrastructure/index.d.mts +30 -6
- package/dist/infrastructure/index.d.ts +30 -6
- package/dist/infrastructure/index.js +80 -29
- package/dist/infrastructure/index.mjs +1 -1
- package/dist/presentation/index.js +186 -63
- package/dist/presentation/index.mjs +3 -3
- package/package.json +1 -1
- package/src/application/services/ScreenshotStudioService.ts +35 -12
- package/src/infrastructure/renderers/CanvasRenderer.ts +30 -3
- package/src/infrastructure/renderers/PatternRenderer.ts +43 -23
- package/src/infrastructure/renderers/ScreenshotRenderer.ts +14 -1
- package/src/infrastructure/services/DeviceConfigService.ts +18 -3
- package/src/presentation/hooks/useCanvasExport.ts +48 -8
- package/src/presentation/hooks/useReportExport.ts +38 -12
- package/src/presentation/hooks/useScreenshotStudio.ts +35 -6
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
var CanvasRenderer = class {
|
|
8
8
|
constructor(config = DEFAULT_CANVAS_CONFIG) {
|
|
9
9
|
this.config = { ...DEFAULT_CANVAS_CONFIG, ...config };
|
|
10
|
+
this.imageCache = /* @__PURE__ */ new Map();
|
|
10
11
|
}
|
|
11
12
|
/**
|
|
12
13
|
* Create a new canvas element
|
|
@@ -108,17 +109,37 @@ var CanvasRenderer = class {
|
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
/**
|
|
111
|
-
* Load image from URL
|
|
112
|
+
* Load image from URL with caching
|
|
112
113
|
*/
|
|
113
114
|
loadImage(url) {
|
|
115
|
+
if (this.imageCache.has(url)) {
|
|
116
|
+
return Promise.resolve(this.imageCache.get(url));
|
|
117
|
+
}
|
|
114
118
|
return new Promise((resolve, reject) => {
|
|
115
119
|
const img = new Image();
|
|
116
|
-
|
|
117
|
-
|
|
120
|
+
if (this.config.useCORS) {
|
|
121
|
+
img.crossOrigin = "anonymous";
|
|
122
|
+
}
|
|
123
|
+
img.onload = () => {
|
|
124
|
+
this.imageCache.set(url, img);
|
|
125
|
+
resolve(img);
|
|
126
|
+
};
|
|
118
127
|
img.onerror = () => reject(new Error(`Failed to load image: ${url}`));
|
|
119
128
|
img.src = url;
|
|
120
129
|
});
|
|
121
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Clear image cache to free memory
|
|
133
|
+
*/
|
|
134
|
+
clearImageCache() {
|
|
135
|
+
this.imageCache.clear();
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get cache size for monitoring
|
|
139
|
+
*/
|
|
140
|
+
getCacheSize() {
|
|
141
|
+
return this.imageCache.size;
|
|
142
|
+
}
|
|
122
143
|
/**
|
|
123
144
|
* Create gradient
|
|
124
145
|
*/
|
|
@@ -200,10 +221,15 @@ var CanvasRenderer = class {
|
|
|
200
221
|
|
|
201
222
|
// src/infrastructure/renderers/PatternRenderer.ts
|
|
202
223
|
var PatternRenderer = class {
|
|
224
|
+
constructor() {
|
|
225
|
+
this.patternCanvasCache = /* @__PURE__ */ new Map();
|
|
226
|
+
this.MAX_CACHE_SIZE = 10;
|
|
227
|
+
}
|
|
203
228
|
/**
|
|
204
229
|
* Render pattern on canvas
|
|
205
230
|
*/
|
|
206
231
|
renderPattern(ctx, pattern, dimensions, color = "#000000") {
|
|
232
|
+
if (pattern === "none") return;
|
|
207
233
|
ctx.save();
|
|
208
234
|
ctx.globalAlpha = 0.1;
|
|
209
235
|
switch (pattern) {
|
|
@@ -222,62 +248,65 @@ var PatternRenderer = class {
|
|
|
222
248
|
case "checkers":
|
|
223
249
|
this.renderCheckerPattern(ctx, dimensions, color);
|
|
224
250
|
break;
|
|
225
|
-
case "none":
|
|
226
|
-
default:
|
|
227
|
-
break;
|
|
228
251
|
}
|
|
229
252
|
ctx.restore();
|
|
230
253
|
}
|
|
231
254
|
/**
|
|
232
|
-
*
|
|
255
|
+
* Clear pattern cache to free memory
|
|
256
|
+
*/
|
|
257
|
+
clearCache() {
|
|
258
|
+
this.patternCanvasCache.clear();
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Render dot pattern - optimized with batch rendering
|
|
233
262
|
*/
|
|
234
263
|
renderDotPattern(ctx, dimensions, color) {
|
|
235
264
|
ctx.fillStyle = color;
|
|
236
265
|
const spacing = 30;
|
|
266
|
+
const radius = 2;
|
|
267
|
+
ctx.beginPath();
|
|
237
268
|
for (let x = spacing; x < dimensions.width; x += spacing) {
|
|
238
269
|
for (let y = spacing; y < dimensions.height; y += spacing) {
|
|
239
|
-
ctx.
|
|
240
|
-
ctx.arc(x, y,
|
|
241
|
-
ctx.fill();
|
|
270
|
+
ctx.moveTo(x + radius, y);
|
|
271
|
+
ctx.arc(x, y, radius, 0, Math.PI * 2);
|
|
242
272
|
}
|
|
243
273
|
}
|
|
274
|
+
ctx.fill();
|
|
244
275
|
}
|
|
245
276
|
/**
|
|
246
|
-
* Render grid pattern
|
|
277
|
+
* Render grid pattern - optimized with single path
|
|
247
278
|
*/
|
|
248
279
|
renderGridPattern(ctx, dimensions, color) {
|
|
249
280
|
ctx.strokeStyle = color;
|
|
250
281
|
ctx.lineWidth = 1;
|
|
251
282
|
const spacing = 30;
|
|
283
|
+
ctx.beginPath();
|
|
252
284
|
for (let x = 0; x <= dimensions.width; x += spacing) {
|
|
253
|
-
ctx.beginPath();
|
|
254
285
|
ctx.moveTo(x, 0);
|
|
255
286
|
ctx.lineTo(x, dimensions.height);
|
|
256
|
-
ctx.stroke();
|
|
257
287
|
}
|
|
258
288
|
for (let y = 0; y <= dimensions.height; y += spacing) {
|
|
259
|
-
ctx.beginPath();
|
|
260
289
|
ctx.moveTo(0, y);
|
|
261
290
|
ctx.lineTo(dimensions.width, y);
|
|
262
|
-
ctx.stroke();
|
|
263
291
|
}
|
|
292
|
+
ctx.stroke();
|
|
264
293
|
}
|
|
265
294
|
/**
|
|
266
|
-
* Render line pattern
|
|
295
|
+
* Render line pattern - optimized with single path
|
|
267
296
|
*/
|
|
268
297
|
renderLinePattern(ctx, dimensions, color) {
|
|
269
298
|
ctx.strokeStyle = color;
|
|
270
299
|
ctx.lineWidth = 2;
|
|
271
300
|
const spacing = 20;
|
|
301
|
+
ctx.beginPath();
|
|
272
302
|
for (let y = spacing; y < dimensions.height; y += spacing) {
|
|
273
|
-
ctx.beginPath();
|
|
274
303
|
ctx.moveTo(0, y);
|
|
275
304
|
ctx.lineTo(dimensions.width, y);
|
|
276
|
-
ctx.stroke();
|
|
277
305
|
}
|
|
306
|
+
ctx.stroke();
|
|
278
307
|
}
|
|
279
308
|
/**
|
|
280
|
-
* Render wave pattern
|
|
309
|
+
* Render wave pattern - optimized with pre-calculated values
|
|
281
310
|
*/
|
|
282
311
|
renderWavePattern(ctx, dimensions, color) {
|
|
283
312
|
ctx.strokeStyle = color;
|
|
@@ -285,15 +314,15 @@ var PatternRenderer = class {
|
|
|
285
314
|
const amplitude = 10;
|
|
286
315
|
const frequency = 0.1;
|
|
287
316
|
const spacing = 40;
|
|
317
|
+
const step = 5;
|
|
288
318
|
for (let y = spacing; y < dimensions.height; y += spacing) {
|
|
289
319
|
ctx.beginPath();
|
|
290
|
-
|
|
320
|
+
const startX = 0;
|
|
321
|
+
const startY = y + Math.sin(startX * frequency) * amplitude;
|
|
322
|
+
ctx.moveTo(startX, startY);
|
|
323
|
+
for (let x = step; x <= dimensions.width; x += step) {
|
|
291
324
|
const waveY = y + Math.sin(x * frequency) * amplitude;
|
|
292
|
-
|
|
293
|
-
ctx.moveTo(x, waveY);
|
|
294
|
-
} else {
|
|
295
|
-
ctx.lineTo(x, waveY);
|
|
296
|
-
}
|
|
325
|
+
ctx.lineTo(x, waveY);
|
|
297
326
|
}
|
|
298
327
|
ctx.stroke();
|
|
299
328
|
}
|
|
@@ -316,6 +345,9 @@ var PatternRenderer = class {
|
|
|
316
345
|
// src/infrastructure/services/DeviceConfigService.ts
|
|
317
346
|
var DeviceConfigService = class _DeviceConfigService {
|
|
318
347
|
constructor() {
|
|
348
|
+
this.phonesCache = null;
|
|
349
|
+
this.tabletsCache = null;
|
|
350
|
+
this.allDevicesCache = null;
|
|
319
351
|
this.devices = /* @__PURE__ */ new Map();
|
|
320
352
|
this.initializeDevices();
|
|
321
353
|
}
|
|
@@ -412,13 +444,22 @@ var DeviceConfigService = class _DeviceConfigService {
|
|
|
412
444
|
return this.devices.get(deviceType);
|
|
413
445
|
}
|
|
414
446
|
getAllDevices() {
|
|
415
|
-
|
|
447
|
+
if (!this.allDevicesCache) {
|
|
448
|
+
this.allDevicesCache = Array.from(this.devices.values());
|
|
449
|
+
}
|
|
450
|
+
return this.allDevicesCache;
|
|
416
451
|
}
|
|
417
452
|
getPhones() {
|
|
418
|
-
|
|
453
|
+
if (!this.phonesCache) {
|
|
454
|
+
this.phonesCache = this.getAllDevices().filter((d) => d.isPhone);
|
|
455
|
+
}
|
|
456
|
+
return this.phonesCache;
|
|
419
457
|
}
|
|
420
458
|
getTablets() {
|
|
421
|
-
|
|
459
|
+
if (!this.tabletsCache) {
|
|
460
|
+
this.tabletsCache = this.getAllDevices().filter((d) => d.isTablet);
|
|
461
|
+
}
|
|
462
|
+
return this.tabletsCache;
|
|
422
463
|
}
|
|
423
464
|
isPhone(deviceType) {
|
|
424
465
|
const config = this.getDeviceConfig(deviceType);
|
|
@@ -437,10 +478,20 @@ var DeviceConfigService = class _DeviceConfigService {
|
|
|
437
478
|
// src/infrastructure/renderers/ScreenshotRenderer.ts
|
|
438
479
|
var ScreenshotRenderer = class {
|
|
439
480
|
constructor() {
|
|
481
|
+
this.renderCache = /* @__PURE__ */ new Map();
|
|
482
|
+
this.MAX_CACHE_SIZE = 5;
|
|
440
483
|
this.canvasRenderer = new CanvasRenderer();
|
|
441
484
|
this.patternRenderer = new PatternRenderer();
|
|
442
485
|
this.deviceConfigService = DeviceConfigService.getInstance();
|
|
443
486
|
}
|
|
487
|
+
/**
|
|
488
|
+
* Clear render cache to free memory
|
|
489
|
+
*/
|
|
490
|
+
clearCache() {
|
|
491
|
+
this.renderCache.clear();
|
|
492
|
+
this.canvasRenderer.clearImageCache?.();
|
|
493
|
+
this.patternRenderer.clearCache?.();
|
|
494
|
+
}
|
|
444
495
|
/**
|
|
445
496
|
* Render device frame
|
|
446
497
|
*/
|
|
@@ -492,7 +543,7 @@ var ScreenshotRenderer = class {
|
|
|
492
543
|
ctx.fill();
|
|
493
544
|
}
|
|
494
545
|
/**
|
|
495
|
-
* Render background
|
|
546
|
+
* Render background - optimized
|
|
496
547
|
*/
|
|
497
548
|
renderBackground(ctx, design, dimensions) {
|
|
498
549
|
if (design.backgroundGradientEnd) {
|