@umituz/web-canvas 1.0.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.
Files changed (55) hide show
  1. package/dist/CanvasConfig-pzoE0RHD.d.mts +310 -0
  2. package/dist/CanvasConfig-pzoE0RHD.d.ts +310 -0
  3. package/dist/application/index.d.mts +78 -0
  4. package/dist/application/index.d.ts +78 -0
  5. package/dist/application/index.js +1083 -0
  6. package/dist/application/index.mjs +11 -0
  7. package/dist/chunk-BN7JTXL7.mjs +346 -0
  8. package/dist/chunk-MC6PNV2F.mjs +34 -0
  9. package/dist/chunk-SF6WND7M.mjs +547 -0
  10. package/dist/chunk-TZGTTYTZ.mjs +0 -0
  11. package/dist/chunk-WMKPCJFI.mjs +661 -0
  12. package/dist/chunk-Z6IB4BQV.mjs +31 -0
  13. package/dist/domain/config/index.d.mts +87 -0
  14. package/dist/domain/config/index.d.ts +87 -0
  15. package/dist/domain/config/index.js +92 -0
  16. package/dist/domain/config/index.mjs +15 -0
  17. package/dist/domain/index.d.mts +79 -0
  18. package/dist/domain/index.d.ts +79 -0
  19. package/dist/domain/index.js +137 -0
  20. package/dist/domain/index.mjs +55 -0
  21. package/dist/index.d.mts +6 -0
  22. package/dist/index.d.ts +6 -0
  23. package/dist/index.js +1633 -0
  24. package/dist/index.mjs +38 -0
  25. package/dist/infrastructure/index.d.mts +174 -0
  26. package/dist/infrastructure/index.d.ts +174 -0
  27. package/dist/infrastructure/index.js +714 -0
  28. package/dist/infrastructure/index.mjs +13 -0
  29. package/dist/presentation/index.d.mts +108 -0
  30. package/dist/presentation/index.d.ts +108 -0
  31. package/dist/presentation/index.js +1617 -0
  32. package/dist/presentation/index.mjs +14 -0
  33. package/package.json +86 -0
  34. package/src/application/index.ts +7 -0
  35. package/src/application/services/ReportService.ts +200 -0
  36. package/src/application/services/ScreenshotStudioService.ts +243 -0
  37. package/src/domain/config/CanvasConfig.ts +36 -0
  38. package/src/domain/config/DeviceConfig.ts +47 -0
  39. package/src/domain/config/ScreenshotStudioConfig.ts +82 -0
  40. package/src/domain/config/index.ts +8 -0
  41. package/src/domain/index.ts +7 -0
  42. package/src/domain/types/canvas.types.ts +85 -0
  43. package/src/domain/types/index.ts +8 -0
  44. package/src/domain/types/report.types.ts +83 -0
  45. package/src/domain/types/screenshot.types.ts +238 -0
  46. package/src/index.ts +102 -0
  47. package/src/infrastructure/index.ts +9 -0
  48. package/src/infrastructure/renderers/CanvasRenderer.ts +287 -0
  49. package/src/infrastructure/renderers/PatternRenderer.ts +160 -0
  50. package/src/infrastructure/renderers/ScreenshotRenderer.ts +331 -0
  51. package/src/infrastructure/services/DeviceConfigService.ts +144 -0
  52. package/src/presentation/hooks/useCanvasExport.ts +162 -0
  53. package/src/presentation/hooks/useReportExport.ts +161 -0
  54. package/src/presentation/hooks/useScreenshotStudio.ts +480 -0
  55. package/src/presentation/index.ts +8 -0
@@ -0,0 +1,547 @@
1
+ import {
2
+ ReportService,
3
+ ScreenshotStudioService
4
+ } from "./chunk-BN7JTXL7.mjs";
5
+ import {
6
+ CanvasRenderer
7
+ } from "./chunk-WMKPCJFI.mjs";
8
+ import {
9
+ DEFAULT_SCREENSHOT_STUDIO_CONFIG
10
+ } from "./chunk-Z6IB4BQV.mjs";
11
+ import {
12
+ DEFAULT_CANVAS_CONFIG
13
+ } from "./chunk-MC6PNV2F.mjs";
14
+
15
+ // src/presentation/hooks/useScreenshotStudio.ts
16
+ import { useState, useCallback, useRef } from "react";
17
+ var DEFAULT_SCREENS = [
18
+ {
19
+ id: "1",
20
+ title: "APPGROWTHFACTORY *MODERN*",
21
+ subtitle: "Create content with AI power",
22
+ screenshot: null,
23
+ translations: {
24
+ "en-US": {
25
+ title: "APPGROWTHFACTORY *MODERN*",
26
+ subtitle: "Create content with AI power"
27
+ },
28
+ "tr-TR": {
29
+ title: "APPGROWTHFACTORY *MODERN*",
30
+ subtitle: "Yapay zeka g\xFCc\xFCyle i\xE7erik \xFCret"
31
+ }
32
+ },
33
+ imageFit: "cover",
34
+ imageZoom: 1,
35
+ imageAnchorX: 50,
36
+ imageAnchorY: 50
37
+ },
38
+ {
39
+ id: "2",
40
+ title: "CONNECT *GLOBAL*",
41
+ subtitle: "Post to all platforms instantly",
42
+ screenshot: null,
43
+ translations: {
44
+ "en-US": {
45
+ title: "CONNECT *GLOBAL*",
46
+ subtitle: "Post to all platforms instantly"
47
+ },
48
+ "tr-TR": {
49
+ title: "BA\u011ELAN *K\xDCRESEL*",
50
+ subtitle: "T\xFCm platformlara an\u0131nda g\xF6nder"
51
+ }
52
+ },
53
+ imageFit: "cover",
54
+ imageZoom: 1,
55
+ imageAnchorX: 50,
56
+ imageAnchorY: 50
57
+ }
58
+ ];
59
+ var DEFAULT_DESIGN = {
60
+ backgroundColor: "#6366f1",
61
+ backgroundGradientEnd: "#a855f7",
62
+ backgroundImage: null,
63
+ backgroundBlur: 0,
64
+ backgroundOverlayOpacity: 0,
65
+ backgroundPattern: "none",
66
+ textColor: "#ffffff",
67
+ highlightColor: "#fbbf24",
68
+ textAlign: "center",
69
+ deviceColor: "#1f2937",
70
+ deviceType: "iphone-15-pro",
71
+ frameStyle: "realistic",
72
+ layout: "text-top",
73
+ scale: 0.85,
74
+ fontFamily: "Inter",
75
+ titleFontSize: 60,
76
+ subtitleFontSize: 24,
77
+ titleFontWeight: "900",
78
+ subtitleFontWeight: "500",
79
+ textCase: "uppercase",
80
+ lineHeight: 0.9,
81
+ letterSpacing: -1,
82
+ rotation: 0,
83
+ rotationX: 0,
84
+ rotationY: 0,
85
+ rotationZ: 0,
86
+ offsetY: 0,
87
+ shadowIntensity: 0.5,
88
+ padding: 40,
89
+ gap: 20,
90
+ isPanoramic: false
91
+ };
92
+ var DEFAULT_APP_METADATA = {
93
+ appName: "Growdo",
94
+ subtitle: "AI Content Generator",
95
+ promotionalText: "Unlock your creative potential",
96
+ keywords: "ai, content, marketing, automation, generator",
97
+ description: "The ultimate tool for AI-powered marketing content.",
98
+ whatsNew: "New Design Studio integration!"
99
+ };
100
+ function useScreenshotStudio(options = {}) {
101
+ const {
102
+ config = {},
103
+ onShowToast = () => {
104
+ }
105
+ } = options;
106
+ const fullConfig = {
107
+ ...DEFAULT_SCREENSHOT_STUDIO_CONFIG,
108
+ ...config
109
+ };
110
+ const serviceRef = useRef(
111
+ new ScreenshotStudioService(fullConfig)
112
+ );
113
+ const [screens, setScreens] = useState(DEFAULT_SCREENS);
114
+ const [design, setDesign] = useState(DEFAULT_DESIGN);
115
+ const [currentLanguage, setCurrentLanguage] = useState(
116
+ fullConfig.defaultLanguage || "en-US"
117
+ );
118
+ const [selectedScreenId, setSelectedScreenId] = useState("1");
119
+ const [isProcessing, setIsProcessing] = useState(false);
120
+ const [isAnalyzing, setIsAnalyzing] = useState(false);
121
+ const [appMetadata, setAppMetadata] = useState(
122
+ DEFAULT_APP_METADATA
123
+ );
124
+ const [appIcon, setAppIcon] = useState(null);
125
+ const [projectId, setProjectId] = useState(null);
126
+ const activeScreen = screens.find((s) => s.id === selectedScreenId) || screens[0];
127
+ const updateDesign = useCallback((updates) => {
128
+ setDesign((prev) => ({ ...prev, ...updates }));
129
+ }, []);
130
+ const updateActiveScreen = useCallback(
131
+ (updates) => {
132
+ setScreens(
133
+ (prev) => prev.map((screen) => {
134
+ if (screen.id !== selectedScreenId) return screen;
135
+ const updatedScreen = { ...screen, ...updates };
136
+ if (updates.title || updates.subtitle) {
137
+ updatedScreen.translations = {
138
+ ...updatedScreen.translations,
139
+ [currentLanguage]: {
140
+ title: updatedScreen.title,
141
+ subtitle: updatedScreen.subtitle
142
+ }
143
+ };
144
+ }
145
+ return updatedScreen;
146
+ })
147
+ );
148
+ },
149
+ [selectedScreenId, currentLanguage]
150
+ );
151
+ const changeLanguage = useCallback(
152
+ (newLanguage) => {
153
+ setCurrentLanguage(newLanguage);
154
+ setScreens(
155
+ (prev) => prev.map((screen) => {
156
+ const translation = screen.translations[newLanguage] || screen.translations["en-US"] || { title: screen.title, subtitle: screen.subtitle };
157
+ return {
158
+ ...screen,
159
+ title: translation.title,
160
+ subtitle: translation.subtitle
161
+ };
162
+ })
163
+ );
164
+ onShowToast("Language Changed", `Switched to ${newLanguage}`);
165
+ },
166
+ [onShowToast]
167
+ );
168
+ const addScreen = useCallback(() => {
169
+ const newScreen = {
170
+ id: Date.now().toString(),
171
+ title: "NEW *POST*",
172
+ subtitle: "Engage your audience",
173
+ screenshot: null,
174
+ translations: {
175
+ [currentLanguage]: {
176
+ title: "NEW *POST*",
177
+ subtitle: "Engage your audience"
178
+ }
179
+ },
180
+ imageFit: "cover",
181
+ imageZoom: 1,
182
+ imageAnchorX: 50,
183
+ imageAnchorY: 50
184
+ };
185
+ setScreens((prev) => [...prev, newScreen]);
186
+ setSelectedScreenId(newScreen.id);
187
+ onShowToast("Success", "New screen added");
188
+ }, [currentLanguage, onShowToast]);
189
+ const removeScreen = useCallback(
190
+ (screenId) => {
191
+ if (screens.length <= 1) return;
192
+ setScreens((prev) => {
193
+ const newScreens = prev.filter((s) => s.id !== screenId);
194
+ if (selectedScreenId === screenId) {
195
+ setSelectedScreenId(newScreens[0].id);
196
+ }
197
+ return newScreens;
198
+ });
199
+ onShowToast("Info", "Screen removed");
200
+ },
201
+ [screens.length, selectedScreenId, onShowToast]
202
+ );
203
+ const duplicateScreen = useCallback(
204
+ (screenId) => {
205
+ const screenToDuplicate = screens.find((s) => s.id === screenId);
206
+ if (!screenToDuplicate) return;
207
+ const newScreen = {
208
+ ...screenToDuplicate,
209
+ id: Date.now().toString(),
210
+ title: `${screenToDuplicate.title} (Copy)`,
211
+ translations: { ...screenToDuplicate.translations }
212
+ };
213
+ setScreens((prev) => {
214
+ const index = prev.findIndex((s) => s.id === screenId);
215
+ const newScreens = [...prev];
216
+ newScreens.splice(index + 1, 0, newScreen);
217
+ return newScreens;
218
+ });
219
+ setSelectedScreenId(newScreen.id);
220
+ onShowToast("Success", "Screen duplicated");
221
+ },
222
+ [screens, onShowToast]
223
+ );
224
+ const applyTemplate = useCallback(
225
+ (template) => {
226
+ setDesign((prev) => ({ ...prev, ...template.design }));
227
+ onShowToast("Template Applied", template.name);
228
+ },
229
+ [onShowToast]
230
+ );
231
+ const generateDesignedScreenshot = useCallback(
232
+ async (screenId) => {
233
+ const screen = screens.find((s) => s.id === screenId);
234
+ if (!screen) return;
235
+ setIsProcessing(true);
236
+ try {
237
+ const result = await serviceRef.current.generateDesignedScreenshot(
238
+ screen,
239
+ design
240
+ );
241
+ onShowToast("Success", "Screenshot generated");
242
+ return { url: result.url, id: result.id };
243
+ } catch {
244
+ onShowToast("Error", "Screenshot generation failed");
245
+ } finally {
246
+ setIsProcessing(false);
247
+ }
248
+ },
249
+ [screens, design, onShowToast]
250
+ );
251
+ const exportAllScreensAsZip = useCallback(
252
+ async (format = "png") => {
253
+ setIsProcessing(true);
254
+ try {
255
+ const project = {
256
+ id: projectId || "default-project",
257
+ name: "Export Project",
258
+ design,
259
+ screens,
260
+ currentLanguage,
261
+ selectedScreenId,
262
+ appMetadata,
263
+ appIcon,
264
+ createdAt: /* @__PURE__ */ new Date(),
265
+ updatedAt: /* @__PURE__ */ new Date()
266
+ };
267
+ const blob = await serviceRef.current.exportProjectAsZip(project);
268
+ const url = URL.createObjectURL(blob);
269
+ const link = document.createElement("a");
270
+ link.href = url;
271
+ link.download = `Studio_${currentLanguage}_${Date.now()}.zip`;
272
+ link.click();
273
+ URL.revokeObjectURL(url);
274
+ onShowToast(
275
+ "Success",
276
+ `Exported ${screens.length} screens in ZIP archive.`
277
+ );
278
+ } catch {
279
+ onShowToast("Error", "ZIP export failed");
280
+ } finally {
281
+ setIsProcessing(false);
282
+ }
283
+ },
284
+ [
285
+ screens,
286
+ design,
287
+ currentLanguage,
288
+ appMetadata,
289
+ appIcon,
290
+ projectId,
291
+ selectedScreenId,
292
+ onShowToast
293
+ ]
294
+ );
295
+ const _getProjectState = useCallback(() => {
296
+ return {
297
+ id: projectId || "appgrowthfactory_main_project",
298
+ name: "Default Project",
299
+ design,
300
+ screens,
301
+ currentLanguage,
302
+ selectedScreenId,
303
+ appMetadata,
304
+ appIcon,
305
+ createdAt: /* @__PURE__ */ new Date(),
306
+ updatedAt: /* @__PURE__ */ new Date()
307
+ };
308
+ }, [
309
+ design,
310
+ screens,
311
+ currentLanguage,
312
+ selectedScreenId,
313
+ appMetadata,
314
+ appIcon,
315
+ projectId
316
+ ]);
317
+ const _loadProjectState = useCallback(
318
+ (state) => {
319
+ if (!state) return;
320
+ if (state.screens) setScreens(state.screens);
321
+ if (state.design) setDesign(state.design);
322
+ if (state.currentLanguage) setCurrentLanguage(state.currentLanguage);
323
+ if (state.selectedScreenId && state.screens?.find((s) => s.id === state.selectedScreenId)) {
324
+ setSelectedScreenId(state.selectedScreenId);
325
+ }
326
+ if (state.appMetadata) setAppMetadata(state.appMetadata);
327
+ if (state.appIcon !== void 0) setAppIcon(state.appIcon);
328
+ },
329
+ []
330
+ );
331
+ return {
332
+ screens,
333
+ design,
334
+ currentLanguage,
335
+ selectedScreenId,
336
+ activeScreen,
337
+ isProcessing,
338
+ isAnalyzing,
339
+ appMetadata,
340
+ appIcon,
341
+ projectId,
342
+ updateDesign,
343
+ updateActiveScreen,
344
+ setSelectedScreenId,
345
+ changeLanguage,
346
+ applyTemplate,
347
+ addScreen,
348
+ removeScreen,
349
+ duplicateScreen,
350
+ generateDesignedScreenshot,
351
+ exportAllScreensAsZip,
352
+ setAppMetadata,
353
+ setAppIcon,
354
+ setProjectId,
355
+ _getProjectState,
356
+ _loadProjectState
357
+ };
358
+ }
359
+
360
+ // src/presentation/hooks/useCanvasExport.ts
361
+ import { useState as useState2, useCallback as useCallback2 } from "react";
362
+ function useCanvasExport(options = {}) {
363
+ const { config = DEFAULT_CANVAS_CONFIG } = options;
364
+ const [isExporting, setIsExporting] = useState2(false);
365
+ const [progress, setProgress] = useState2(0);
366
+ const [error, setError] = useState2(null);
367
+ const renderer = new CanvasRenderer(config);
368
+ const exportToBlob = useCallback2(
369
+ async (canvas, options2) => {
370
+ setIsExporting(true);
371
+ setProgress(0);
372
+ setError(null);
373
+ try {
374
+ const result = await renderer.exportToBlob(canvas, options2);
375
+ setProgress(100);
376
+ return result;
377
+ } catch (err) {
378
+ const errorMessage = err instanceof Error ? err.message : "Export failed";
379
+ setError(errorMessage);
380
+ return null;
381
+ } finally {
382
+ setIsExporting(false);
383
+ }
384
+ },
385
+ [renderer]
386
+ );
387
+ const exportToDataURL = useCallback2(
388
+ (canvas, format, quality) => {
389
+ try {
390
+ return renderer.exportToDataURL(canvas, format, quality);
391
+ } catch (err) {
392
+ const errorMessage = err instanceof Error ? err.message : "Export failed";
393
+ setError(errorMessage);
394
+ return null;
395
+ }
396
+ },
397
+ [renderer]
398
+ );
399
+ const downloadCanvas = useCallback2(
400
+ async (canvas, filename, options2) => {
401
+ setIsExporting(true);
402
+ setProgress(0);
403
+ setError(null);
404
+ try {
405
+ const result = await exportToBlob(canvas, options2);
406
+ if (!result) {
407
+ throw new Error("Export failed");
408
+ }
409
+ setProgress(50);
410
+ const link = document.createElement("a");
411
+ link.href = result.url;
412
+ link.download = filename;
413
+ link.click();
414
+ setProgress(100);
415
+ setTimeout(() => {
416
+ URL.revokeObjectURL(result.url);
417
+ }, 100);
418
+ } catch (err) {
419
+ const errorMessage = err instanceof Error ? err.message : "Download failed";
420
+ setError(errorMessage);
421
+ } finally {
422
+ setIsExporting(false);
423
+ }
424
+ },
425
+ [exportToBlob]
426
+ );
427
+ const cloneCanvas = useCallback2(
428
+ (canvas) => {
429
+ try {
430
+ return renderer.cloneCanvas(canvas);
431
+ } catch (err) {
432
+ const errorMessage = err instanceof Error ? err.message : "Clone failed";
433
+ setError(errorMessage);
434
+ return null;
435
+ }
436
+ },
437
+ [renderer]
438
+ );
439
+ return {
440
+ isExporting,
441
+ progress,
442
+ error,
443
+ exportToBlob,
444
+ exportToDataURL,
445
+ downloadCanvas,
446
+ cloneCanvas
447
+ };
448
+ }
449
+
450
+ // src/presentation/hooks/useReportExport.ts
451
+ import { useState as useState3, useCallback as useCallback3 } from "react";
452
+ function useReportExport() {
453
+ const [isExporting, setIsExporting] = useState3(false);
454
+ const [error, setError] = useState3(null);
455
+ const reportService = ReportService.getInstance();
456
+ const exportToPDF = useCallback3(
457
+ async (elementId, options) => {
458
+ setIsExporting(true);
459
+ setError(null);
460
+ try {
461
+ await reportService.exportToPDF(elementId, options);
462
+ } catch (err) {
463
+ const errorMessage = err instanceof Error ? err.message : "PDF export failed";
464
+ setError(errorMessage);
465
+ throw err;
466
+ } finally {
467
+ setIsExporting(false);
468
+ }
469
+ },
470
+ [reportService]
471
+ );
472
+ const exportCanvasToPDF = useCallback3(
473
+ async (canvas, options) => {
474
+ setIsExporting(true);
475
+ setError(null);
476
+ try {
477
+ await reportService.exportCanvasToPDF(canvas, options);
478
+ } catch (err) {
479
+ const errorMessage = err instanceof Error ? err.message : "Canvas PDF export failed";
480
+ setError(errorMessage);
481
+ throw err;
482
+ } finally {
483
+ setIsExporting(false);
484
+ }
485
+ },
486
+ [reportService]
487
+ );
488
+ const exportMultipleToPDF = useCallback3(
489
+ async (elementIds, options) => {
490
+ setIsExporting(true);
491
+ setError(null);
492
+ try {
493
+ await reportService.exportMultipleToPDF(elementIds, options);
494
+ } catch (err) {
495
+ const errorMessage = err instanceof Error ? err.message : "Multi-page PDF export failed";
496
+ setError(errorMessage);
497
+ throw err;
498
+ } finally {
499
+ setIsExporting(false);
500
+ }
501
+ },
502
+ [reportService]
503
+ );
504
+ const exportToExcel = useCallback3(
505
+ async (data, options) => {
506
+ setIsExporting(true);
507
+ setError(null);
508
+ try {
509
+ await reportService.exportToExcel(data, options);
510
+ } catch (err) {
511
+ const errorMessage = err instanceof Error ? err.message : "Excel export failed";
512
+ setError(errorMessage);
513
+ throw err;
514
+ } finally {
515
+ setIsExporting(false);
516
+ }
517
+ },
518
+ [reportService]
519
+ );
520
+ const exportToCSV = useCallback3(
521
+ (data, filename, delimiter) => {
522
+ try {
523
+ reportService.exportToCSV(data, filename, delimiter);
524
+ } catch (err) {
525
+ const errorMessage = err instanceof Error ? err.message : "CSV export failed";
526
+ setError(errorMessage);
527
+ throw err;
528
+ }
529
+ },
530
+ [reportService]
531
+ );
532
+ return {
533
+ isExporting,
534
+ error,
535
+ exportToPDF,
536
+ exportCanvasToPDF,
537
+ exportMultipleToPDF,
538
+ exportToExcel,
539
+ exportToCSV
540
+ };
541
+ }
542
+
543
+ export {
544
+ useScreenshotStudio,
545
+ useCanvasExport,
546
+ useReportExport
547
+ };
File without changes