@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,11 @@
1
+ import {
2
+ ReportService,
3
+ ScreenshotStudioService
4
+ } from "../chunk-BN7JTXL7.mjs";
5
+ import "../chunk-WMKPCJFI.mjs";
6
+ import "../chunk-Z6IB4BQV.mjs";
7
+ import "../chunk-MC6PNV2F.mjs";
8
+ export {
9
+ ReportService,
10
+ ScreenshotStudioService
11
+ };
@@ -0,0 +1,346 @@
1
+ import {
2
+ ScreenshotRenderer
3
+ } from "./chunk-WMKPCJFI.mjs";
4
+ import {
5
+ DEFAULT_SCREENSHOT_STUDIO_CONFIG
6
+ } from "./chunk-Z6IB4BQV.mjs";
7
+
8
+ // src/application/services/ScreenshotStudioService.ts
9
+ var ScreenshotStudioService = class {
10
+ constructor(config) {
11
+ this.config = {
12
+ ...DEFAULT_SCREENSHOT_STUDIO_CONFIG,
13
+ ...config
14
+ };
15
+ this.renderer = new ScreenshotRenderer();
16
+ }
17
+ /**
18
+ * Generate screenshot
19
+ */
20
+ async generateScreenshot(options) {
21
+ const deviceConfig = this.config.device?.devices.find(
22
+ (d) => d === options.deviceType
23
+ );
24
+ if (!deviceConfig) {
25
+ throw new Error(`Device configuration not found for ${options.deviceType}`);
26
+ }
27
+ const canvas = this.renderer["canvasRenderer"].createCanvas(
28
+ options.customDimensions || { width: 1290, height: 2796 }
29
+ );
30
+ const ctx = canvas.getContext("2d");
31
+ if (!ctx) {
32
+ throw new Error("Failed to get canvas context");
33
+ }
34
+ this.renderer["renderPlaceholderContent"](
35
+ ctx,
36
+ { width: canvas.width, height: canvas.height },
37
+ options.deviceType
38
+ );
39
+ const blob = await this.renderer["canvasRenderer"].exportToBlob(canvas, {
40
+ format: options.format || this.config.export?.defaultFormat || "png",
41
+ quality: options.quality || this.config.canvas?.defaultQuality || 0.9
42
+ });
43
+ return {
44
+ id: this.generateId(),
45
+ deviceType: options.deviceType,
46
+ dimensions: { width: canvas.width, height: canvas.height },
47
+ format: options.format || this.config.export?.defaultFormat || "png",
48
+ timestamp: /* @__PURE__ */ new Date(),
49
+ fileSize: blob.blob.size,
50
+ url: blob.url
51
+ };
52
+ }
53
+ /**
54
+ * Generate batch screenshots
55
+ */
56
+ async generateBatchScreenshots(deviceTypes) {
57
+ const promises = deviceTypes.map(
58
+ (deviceType) => this.generateScreenshot({ deviceType })
59
+ );
60
+ return Promise.all(promises);
61
+ }
62
+ /**
63
+ * Generate designed screenshot
64
+ */
65
+ async generateDesignedScreenshot(content, design) {
66
+ const canvas = await this.renderer.renderDesignedScreenshot(content, design);
67
+ const blob = await this.renderer["canvasRenderer"].exportToBlob(canvas, {
68
+ format: "png"
69
+ });
70
+ return {
71
+ id: this.generateId(),
72
+ deviceType: design.deviceType,
73
+ dimensions: { width: canvas.width, height: canvas.height },
74
+ format: "png",
75
+ timestamp: /* @__PURE__ */ new Date(),
76
+ fileSize: blob.blob.size,
77
+ url: blob.url
78
+ };
79
+ }
80
+ /**
81
+ * Export project as ZIP
82
+ */
83
+ async exportProjectAsZip(project) {
84
+ const JSZip = (await import("jszip")).default;
85
+ const zip = new JSZip();
86
+ const folder = zip.folder(project.currentLanguage);
87
+ if (!folder) {
88
+ throw new Error("Failed to create folder in ZIP");
89
+ }
90
+ if (this.config.export?.includeMetadata) {
91
+ const metadataText = `APP NAME: ${project.appMetadata.appName}
92
+ SUBTITLE: ${project.appMetadata.subtitle}
93
+ DESCRIPTION:
94
+ ${project.appMetadata.description}
95
+
96
+ KEYWORDS: ${project.appMetadata.keywords}
97
+ WHATS NEW:
98
+ ${project.appMetadata.whatsNew}`;
99
+ folder.file("aso_metadata.txt", metadataText);
100
+ }
101
+ for (let i = 0; i < project.screens.length; i++) {
102
+ const screen = project.screens[i];
103
+ const screenshot = await this.generateDesignedScreenshot(screen, project.design);
104
+ const base64Data = screenshot.url.split(",")[1];
105
+ folder.file(
106
+ `screen_${i + 1}_${project.design.deviceType}.png`,
107
+ base64Data,
108
+ { base64: true }
109
+ );
110
+ }
111
+ return await zip.generateAsync({ type: "blob" });
112
+ }
113
+ /**
114
+ * Create project
115
+ */
116
+ createProject(name) {
117
+ return {
118
+ id: this.generateId(),
119
+ name,
120
+ design: this.getDefaultDesign(),
121
+ screens: [this.getDefaultScreen()],
122
+ currentLanguage: this.config.defaultLanguage || "en-US",
123
+ selectedScreenId: "1",
124
+ appMetadata: {
125
+ appName: "My App",
126
+ subtitle: "App Description",
127
+ promotionalText: "Promotional text",
128
+ keywords: "keyword1, keyword2",
129
+ description: "App description",
130
+ whatsNew: "What is new in this version"
131
+ },
132
+ appIcon: null,
133
+ createdAt: /* @__PURE__ */ new Date(),
134
+ updatedAt: /* @__PURE__ */ new Date()
135
+ };
136
+ }
137
+ /**
138
+ * Get default design
139
+ */
140
+ getDefaultDesign() {
141
+ return {
142
+ backgroundColor: "#6366f1",
143
+ backgroundGradientEnd: "#a855f7",
144
+ backgroundImage: null,
145
+ backgroundBlur: 0,
146
+ backgroundOverlayOpacity: 0,
147
+ backgroundPattern: "none",
148
+ textColor: "#ffffff",
149
+ highlightColor: "#fbbf24",
150
+ textAlign: "center",
151
+ deviceColor: "#1f2937",
152
+ deviceType: this.config.device?.defaultDevice || "iphone-15-pro",
153
+ frameStyle: "realistic",
154
+ layout: "text-top",
155
+ scale: 0.85,
156
+ fontFamily: "Inter",
157
+ titleFontSize: 60,
158
+ subtitleFontSize: 24,
159
+ titleFontWeight: "900",
160
+ subtitleFontWeight: "500",
161
+ textCase: "uppercase",
162
+ lineHeight: 0.9,
163
+ letterSpacing: -1,
164
+ rotation: 0,
165
+ rotationX: 0,
166
+ rotationY: 0,
167
+ rotationZ: 0,
168
+ offsetY: 0,
169
+ shadowIntensity: 0.5,
170
+ padding: 40,
171
+ gap: 20,
172
+ isPanoramic: false
173
+ };
174
+ }
175
+ /**
176
+ * Get default screen
177
+ */
178
+ getDefaultScreen() {
179
+ return {
180
+ id: "1",
181
+ title: "MY *APP*",
182
+ subtitle: "Your app description here",
183
+ screenshot: null,
184
+ translations: {
185
+ "en-US": { title: "MY *APP*", subtitle: "Your app description here" }
186
+ },
187
+ imageFit: "cover",
188
+ imageZoom: 1,
189
+ imageAnchorX: 50,
190
+ imageAnchorY: 50
191
+ };
192
+ }
193
+ /**
194
+ * Generate unique ID
195
+ */
196
+ generateId() {
197
+ return Math.random().toString(36).substr(2, 9);
198
+ }
199
+ };
200
+
201
+ // src/application/services/ReportService.ts
202
+ var ReportService = class _ReportService {
203
+ static getInstance() {
204
+ if (!_ReportService.instance) {
205
+ _ReportService.instance = new _ReportService();
206
+ }
207
+ return _ReportService.instance;
208
+ }
209
+ /**
210
+ * Export DOM element to PDF
211
+ */
212
+ async exportToPDF(elementId, options = {}) {
213
+ const html2canvas = (await import("html2canvas")).default;
214
+ const jsPDF = (await import("jspdf")).default;
215
+ const element = document.getElementById(elementId);
216
+ if (!element) {
217
+ throw new Error("Report element not found");
218
+ }
219
+ const canvas = await html2canvas(element, {
220
+ scale: options.scale || 2,
221
+ useCORS: options.useCORS !== false,
222
+ backgroundColor: options.backgroundColor || "#ffffff"
223
+ });
224
+ const imgData = canvas.toDataURL("image/png");
225
+ const pdf = new jsPDF("p", "mm", "a4");
226
+ const imgWidth = 210;
227
+ const imgHeight = canvas.height * imgWidth / canvas.width;
228
+ pdf.addImage(imgData, "PNG", 0, 0, imgWidth, imgHeight);
229
+ pdf.save(options.filename || "report.pdf");
230
+ }
231
+ /**
232
+ * Export canvas to PDF
233
+ */
234
+ async exportCanvasToPDF(canvas, options = {}) {
235
+ const jsPDF = (await import("jspdf")).default;
236
+ const imgData = canvas.toDataURL("image/png");
237
+ const pdf = new jsPDF("p", "mm", "a4");
238
+ const imgWidth = 210;
239
+ const imgHeight = canvas.height * imgWidth / canvas.width;
240
+ pdf.addImage(imgData, "PNG", 0, 0, imgWidth, imgHeight);
241
+ pdf.save(options.filename || "canvas-export.pdf");
242
+ }
243
+ /**
244
+ * Export data to Excel
245
+ */
246
+ async exportToExcel(data, options = {}) {
247
+ const XLSX = await import("xlsx");
248
+ const wb = XLSX.utils.book_new();
249
+ const apps = data.items.filter((i) => i.type === "app").map((i) => ({ Name: i.name, ...i.metrics, ...i.details }));
250
+ const campaigns = data.items.filter((i) => i.type === "campaign").map((i) => ({ Name: i.name, ...i.metrics, ...i.details }));
251
+ const posts = data.items.filter((i) => i.type === "post").map((i) => ({ Name: i.name, ...i.metrics, ...i.details }));
252
+ if (apps.length > 0) {
253
+ XLSX.utils.book_append_sheet(
254
+ wb,
255
+ XLSX.utils.json_to_sheet(apps),
256
+ options.sheetName || "Apps"
257
+ );
258
+ }
259
+ if (campaigns.length > 0) {
260
+ XLSX.utils.book_append_sheet(
261
+ wb,
262
+ XLSX.utils.json_to_sheet(campaigns),
263
+ "Campaigns"
264
+ );
265
+ }
266
+ if (posts.length > 0) {
267
+ XLSX.utils.book_append_sheet(
268
+ wb,
269
+ XLSX.utils.json_to_sheet(posts),
270
+ "Posts"
271
+ );
272
+ }
273
+ if (options.includeSummary !== false) {
274
+ const summary = [
275
+ { Metric: "Total Reach", Value: data.summary.totalReach },
276
+ {
277
+ Metric: "Total Engagement",
278
+ Value: data.summary.totalEngagement
279
+ },
280
+ {
281
+ Metric: "Average Score",
282
+ Value: data.summary.averageScore
283
+ },
284
+ {
285
+ Metric: "Export Date",
286
+ Value: (/* @__PURE__ */ new Date()).toLocaleDateString()
287
+ }
288
+ ];
289
+ XLSX.utils.book_append_sheet(
290
+ wb,
291
+ XLSX.utils.json_to_sheet(summary),
292
+ "Summary"
293
+ );
294
+ }
295
+ XLSX.writeFile(wb, options.filename || "report.xlsx");
296
+ }
297
+ /**
298
+ * Export data to CSV
299
+ */
300
+ exportToCSV(data, filename = "report.csv", delimiter = ",") {
301
+ const headers = ["Type", "Name", "Metrics"];
302
+ const rows = data.items.map((item) => [
303
+ item.type,
304
+ item.name,
305
+ JSON.stringify(item.metrics)
306
+ ]);
307
+ const csvContent = [headers, ...rows].map((row) => row.map((cell) => `"${cell}"`).join(delimiter)).join("\n");
308
+ const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
309
+ const url = URL.createObjectURL(blob);
310
+ const link = document.createElement("a");
311
+ link.href = url;
312
+ link.download = filename;
313
+ link.click();
314
+ URL.revokeObjectURL(url);
315
+ }
316
+ /**
317
+ * Export multiple elements to PDF
318
+ */
319
+ async exportMultipleToPDF(elementIds, options = {}) {
320
+ const html2canvas = (await import("html2canvas")).default;
321
+ const jsPDF = (await import("jspdf")).default;
322
+ const pdf = new jsPDF("p", "mm", "a4");
323
+ for (let i = 0; i < elementIds.length; i++) {
324
+ const element = document.getElementById(elementIds[i]);
325
+ if (!element) continue;
326
+ const canvas = await html2canvas(element, {
327
+ scale: options.scale || 2,
328
+ useCORS: options.useCORS !== false,
329
+ backgroundColor: options.backgroundColor || "#ffffff"
330
+ });
331
+ const imgData = canvas.toDataURL("image/png");
332
+ const imgWidth = 210;
333
+ const imgHeight = canvas.height * imgWidth / canvas.width;
334
+ if (i > 0) {
335
+ pdf.addPage();
336
+ }
337
+ pdf.addImage(imgData, "PNG", 0, 0, imgWidth, imgHeight);
338
+ }
339
+ pdf.save(options.filename || "multi-page-report.pdf");
340
+ }
341
+ };
342
+
343
+ export {
344
+ ScreenshotStudioService,
345
+ ReportService
346
+ };
@@ -0,0 +1,34 @@
1
+ // src/domain/config/CanvasConfig.ts
2
+ var DEFAULT_CANVAS_CONFIG = {
3
+ defaultFormat: "png",
4
+ defaultQuality: 0.9,
5
+ maxDimension: 4096,
6
+ scale: 2,
7
+ backgroundColor: "#ffffff",
8
+ useCORS: true
9
+ };
10
+
11
+ // src/domain/config/DeviceConfig.ts
12
+ var DEVICE_DIMENSIONS = {
13
+ "iphone-15-pro": { width: 1290, height: 2796 },
14
+ "iphone-15": { width: 1179, height: 2556 },
15
+ "iphone-se": { width: 1080, height: 2340 },
16
+ "ipad-pro": { width: 2048, height: 2732 },
17
+ "ipad": { width: 1620, height: 2160 },
18
+ "android-phone": { width: 1440, height: 3120 },
19
+ "android-tablet": { width: 2e3, height: 2200 },
20
+ "desktop": { width: 1920, height: 1080 }
21
+ };
22
+ var DEFAULT_DEVICE_CONFIG = {
23
+ devices: Object.keys(DEVICE_DIMENSIONS),
24
+ defaultDevice: "iphone-15-pro",
25
+ showFrame: true,
26
+ frameColor: "#1f2937",
27
+ frameThickness: 8
28
+ };
29
+
30
+ export {
31
+ DEFAULT_CANVAS_CONFIG,
32
+ DEVICE_DIMENSIONS,
33
+ DEFAULT_DEVICE_CONFIG
34
+ };