@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,14 @@
1
+ import {
2
+ useCanvasExport,
3
+ useReportExport,
4
+ useScreenshotStudio
5
+ } from "../chunk-SF6WND7M.mjs";
6
+ import "../chunk-BN7JTXL7.mjs";
7
+ import "../chunk-WMKPCJFI.mjs";
8
+ import "../chunk-Z6IB4BQV.mjs";
9
+ import "../chunk-MC6PNV2F.mjs";
10
+ export {
11
+ useCanvasExport,
12
+ useReportExport,
13
+ useScreenshotStudio
14
+ };
package/package.json ADDED
@@ -0,0 +1,86 @@
1
+ {
2
+ "name": "@umituz/web-canvas",
3
+ "version": "1.0.0",
4
+ "description": "Comprehensive canvas and screenshot generation library with device frames, patterns, and PDF export",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "sideEffects": false,
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.mjs",
16
+ "require": "./dist/index.js"
17
+ },
18
+ "./domain": {
19
+ "types": "./dist/domain/index.d.ts",
20
+ "import": "./dist/domain/index.mjs",
21
+ "require": "./dist/domain/index.js"
22
+ },
23
+ "./services": {
24
+ "types": "./dist/application/index.d.ts",
25
+ "import": "./dist/application/index.mjs",
26
+ "require": "./dist/application/index.js"
27
+ },
28
+ "./hooks": {
29
+ "types": "./dist/presentation/index.d.ts",
30
+ "import": "./dist/presentation/index.mjs",
31
+ "require": "./dist/presentation/index.js"
32
+ },
33
+ "./renderers": {
34
+ "types": "./dist/infrastructure/index.d.ts",
35
+ "import": "./dist/infrastructure/index.mjs",
36
+ "require": "./dist/infrastructure/index.js"
37
+ },
38
+ "./config": {
39
+ "types": "./dist/domain/config/index.d.ts",
40
+ "import": "./dist/domain/config/index.mjs",
41
+ "require": "./dist/domain/config/index.js"
42
+ }
43
+ },
44
+ "files": [
45
+ "dist",
46
+ "src"
47
+ ],
48
+ "scripts": {
49
+ "build": "tsup src/index.ts src/domain/index.ts src/application/index.ts src/presentation/index.ts src/infrastructure/index.ts src/domain/config/index.ts --format cjs,esm --dts --clean --external react",
50
+ "dev": "tsup src/index.ts src/domain/index.ts src/application/index.ts src/presentation/index.ts src/infrastructure/index.ts src/domain/config/index.ts --format cjs,esm --dts --watch --external react",
51
+ "lint": "tsc --noEmit"
52
+ },
53
+ "keywords": [
54
+ "canvas",
55
+ "screenshot",
56
+ "app-store",
57
+ "google-play",
58
+ "device-frame",
59
+ "pdf-export",
60
+ "html2canvas",
61
+ "jspdf",
62
+ "screenshot-generator",
63
+ "mobile-frame",
64
+ "ios-screenshot",
65
+ "android-screenshot",
66
+ "typescript",
67
+ "react",
68
+ "screenshot-studio"
69
+ ],
70
+ "author": "umituz",
71
+ "license": "MIT",
72
+ "peerDependencies": {
73
+ "react": ">=18"
74
+ },
75
+ "devDependencies": {
76
+ "@types/react": "^18.2.0",
77
+ "tsup": "^8.0.0",
78
+ "typescript": "^5.0.0"
79
+ },
80
+ "dependencies": {
81
+ "html2canvas": "^1.4.1",
82
+ "jspdf": "^4.2.1",
83
+ "jszip": "^3.10.1",
84
+ "xlsx": "^0.18.5"
85
+ }
86
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Application Layer Index
3
+ * Export all application services
4
+ */
5
+
6
+ export * from './services/ScreenshotStudioService';
7
+ export * from './services/ReportService';
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Report Service
3
+ * PDF export and report generation service
4
+ */
5
+
6
+ import type { ReportData } from '../../domain/types/report.types';
7
+ import type { PDFExportOptions, ExcelExportOptions } from '../../domain/types/report.types';
8
+
9
+ export class ReportService {
10
+ private static instance: ReportService;
11
+
12
+ public static getInstance(): ReportService {
13
+ if (!ReportService.instance) {
14
+ ReportService.instance = new ReportService();
15
+ }
16
+ return ReportService.instance;
17
+ }
18
+
19
+ /**
20
+ * Export DOM element to PDF
21
+ */
22
+ async exportToPDF(
23
+ elementId: string,
24
+ options: PDFExportOptions = {}
25
+ ): Promise<void> {
26
+ const html2canvas = (await import('html2canvas')).default;
27
+ const jsPDF = (await import('jspdf')).default;
28
+
29
+ const element = document.getElementById(elementId);
30
+ if (!element) {
31
+ throw new Error('Report element not found');
32
+ }
33
+
34
+ const canvas = await html2canvas(element, {
35
+ scale: options.scale || 2,
36
+ useCORS: options.useCORS !== false,
37
+ backgroundColor: options.backgroundColor || '#ffffff',
38
+ });
39
+
40
+ const imgData = canvas.toDataURL('image/png');
41
+ const pdf = new jsPDF('p', 'mm', 'a4');
42
+ const imgWidth = 210;
43
+ const imgHeight = (canvas.height * imgWidth) / canvas.width;
44
+
45
+ pdf.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight);
46
+ pdf.save(options.filename || 'report.pdf');
47
+ }
48
+
49
+ /**
50
+ * Export canvas to PDF
51
+ */
52
+ async exportCanvasToPDF(
53
+ canvas: HTMLCanvasElement,
54
+ options: PDFExportOptions = {}
55
+ ): Promise<void> {
56
+ const jsPDF = (await import('jspdf')).default;
57
+
58
+ const imgData = canvas.toDataURL('image/png');
59
+ const pdf = new jsPDF('p', 'mm', 'a4');
60
+ const imgWidth = 210;
61
+ const imgHeight = (canvas.height * imgWidth) / canvas.width;
62
+
63
+ pdf.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight);
64
+ pdf.save(options.filename || 'canvas-export.pdf');
65
+ }
66
+
67
+ /**
68
+ * Export data to Excel
69
+ */
70
+ async exportToExcel(
71
+ data: ReportData,
72
+ options: ExcelExportOptions = {}
73
+ ): Promise<void> {
74
+ const XLSX = await import('xlsx');
75
+ const wb = XLSX.utils.book_new();
76
+
77
+ // Group items by type
78
+ const apps = data.items
79
+ .filter((i) => i.type === 'app')
80
+ .map((i) => ({ Name: i.name, ...i.metrics, ...i.details }));
81
+ const campaigns = data.items
82
+ .filter((i) => i.type === 'campaign')
83
+ .map((i) => ({ Name: i.name, ...i.metrics, ...i.details }));
84
+ const posts = data.items
85
+ .filter((i) => i.type === 'post')
86
+ .map((i) => ({ Name: i.name, ...i.metrics, ...i.details }));
87
+
88
+ if (apps.length > 0) {
89
+ XLSX.utils.book_append_sheet(
90
+ wb,
91
+ XLSX.utils.json_to_sheet(apps),
92
+ options.sheetName || 'Apps'
93
+ );
94
+ }
95
+ if (campaigns.length > 0) {
96
+ XLSX.utils.book_append_sheet(
97
+ wb,
98
+ XLSX.utils.json_to_sheet(campaigns),
99
+ 'Campaigns'
100
+ );
101
+ }
102
+ if (posts.length > 0) {
103
+ XLSX.utils.book_append_sheet(
104
+ wb,
105
+ XLSX.utils.json_to_sheet(posts),
106
+ 'Posts'
107
+ );
108
+ }
109
+
110
+ // Summary sheet
111
+ if (options.includeSummary !== false) {
112
+ const summary = [
113
+ { Metric: 'Total Reach', Value: data.summary.totalReach },
114
+ {
115
+ Metric: 'Total Engagement',
116
+ Value: data.summary.totalEngagement,
117
+ },
118
+ {
119
+ Metric: 'Average Score',
120
+ Value: data.summary.averageScore,
121
+ },
122
+ {
123
+ Metric: 'Export Date',
124
+ Value: new Date().toLocaleDateString(),
125
+ },
126
+ ];
127
+ XLSX.utils.book_append_sheet(
128
+ wb,
129
+ XLSX.utils.json_to_sheet(summary),
130
+ 'Summary'
131
+ );
132
+ }
133
+
134
+ XLSX.writeFile(wb, options.filename || 'report.xlsx');
135
+ }
136
+
137
+ /**
138
+ * Export data to CSV
139
+ */
140
+ exportToCSV(
141
+ data: ReportData,
142
+ filename: string = 'report.csv',
143
+ delimiter: ',' | ';' = ','
144
+ ): void {
145
+ const headers = ['Type', 'Name', 'Metrics'];
146
+ const rows = data.items.map((item) => [
147
+ item.type,
148
+ item.name,
149
+ JSON.stringify(item.metrics),
150
+ ]);
151
+
152
+ const csvContent = [headers, ...rows]
153
+ .map((row) => row.map((cell) => `"${cell}"`).join(delimiter))
154
+ .join('\n');
155
+
156
+ const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
157
+ const url = URL.createObjectURL(blob);
158
+ const link = document.createElement('a');
159
+ link.href = url;
160
+ link.download = filename;
161
+ link.click();
162
+ URL.revokeObjectURL(url);
163
+ }
164
+
165
+ /**
166
+ * Export multiple elements to PDF
167
+ */
168
+ async exportMultipleToPDF(
169
+ elementIds: string[],
170
+ options: PDFExportOptions = {}
171
+ ): Promise<void> {
172
+ const html2canvas = (await import('html2canvas')).default;
173
+ const jsPDF = (await import('jspdf')).default;
174
+
175
+ const pdf = new jsPDF('p', 'mm', 'a4');
176
+
177
+ for (let i = 0; i < elementIds.length; i++) {
178
+ const element = document.getElementById(elementIds[i]);
179
+ if (!element) continue;
180
+
181
+ const canvas = await html2canvas(element, {
182
+ scale: options.scale || 2,
183
+ useCORS: options.useCORS !== false,
184
+ backgroundColor: options.backgroundColor || '#ffffff',
185
+ });
186
+
187
+ const imgData = canvas.toDataURL('image/png');
188
+ const imgWidth = 210;
189
+ const imgHeight = (canvas.height * imgWidth) / canvas.width;
190
+
191
+ if (i > 0) {
192
+ pdf.addPage();
193
+ }
194
+
195
+ pdf.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight);
196
+ }
197
+
198
+ pdf.save(options.filename || 'multi-page-report.pdf');
199
+ }
200
+ }
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Screenshot Studio Service
3
+ * High-level screenshot generation service
4
+ */
5
+
6
+ import type {
7
+ ScreenshotContent,
8
+ ScreenshotDesign,
9
+ ScreenshotMetadata,
10
+ ScreenshotGenerationOptions,
11
+ ScreenshotProject,
12
+ DeviceType,
13
+ ScreenshotFormat,
14
+ } from '../../domain/types/screenshot.types';
15
+ import type { ScreenshotStudioConfig } from '../../domain/config/ScreenshotStudioConfig';
16
+ import { DEFAULT_SCREENSHOT_STUDIO_CONFIG } from '../../domain/config/ScreenshotStudioConfig';
17
+ import { ScreenshotRenderer } from '../../infrastructure/renderers/ScreenshotRenderer';
18
+
19
+ export class ScreenshotStudioService {
20
+ private renderer: ScreenshotRenderer;
21
+ private config: ScreenshotStudioConfig;
22
+
23
+ constructor(config?: Partial<ScreenshotStudioConfig>) {
24
+ this.config = {
25
+ ...DEFAULT_SCREENSHOT_STUDIO_CONFIG,
26
+ ...config,
27
+ };
28
+ this.renderer = new ScreenshotRenderer();
29
+ }
30
+
31
+ /**
32
+ * Generate screenshot
33
+ */
34
+ public async generateScreenshot(
35
+ options: ScreenshotGenerationOptions
36
+ ): Promise<ScreenshotMetadata> {
37
+ const deviceConfig = this.config.device?.devices.find(
38
+ (d) => d === options.deviceType
39
+ );
40
+
41
+ if (!deviceConfig) {
42
+ throw new Error(`Device configuration not found for ${options.deviceType}`);
43
+ }
44
+
45
+ const canvas = this.renderer['canvasRenderer'].createCanvas(
46
+ options.customDimensions || { width: 1290, height: 2796 }
47
+ );
48
+ const ctx = canvas.getContext('2d');
49
+
50
+ if (!ctx) {
51
+ throw new Error('Failed to get canvas context');
52
+ }
53
+
54
+ this.renderer['renderPlaceholderContent'](
55
+ ctx,
56
+ { width: canvas.width, height: canvas.height },
57
+ options.deviceType
58
+ );
59
+
60
+ const blob = await this.renderer['canvasRenderer'].exportToBlob(canvas, {
61
+ format: (options.format || this.config.export?.defaultFormat || 'png') as ScreenshotFormat,
62
+ quality: options.quality || this.config.canvas?.defaultQuality || 0.9,
63
+ });
64
+
65
+ return {
66
+ id: this.generateId(),
67
+ deviceType: options.deviceType,
68
+ dimensions: { width: canvas.width, height: canvas.height },
69
+ format: options.format || this.config.export?.defaultFormat || 'png',
70
+ timestamp: new Date(),
71
+ fileSize: blob.blob.size,
72
+ url: blob.url,
73
+ };
74
+ }
75
+
76
+ /**
77
+ * Generate batch screenshots
78
+ */
79
+ public async generateBatchScreenshots(
80
+ deviceTypes: DeviceType[]
81
+ ): Promise<ScreenshotMetadata[]> {
82
+ const promises = deviceTypes.map((deviceType) =>
83
+ this.generateScreenshot({ deviceType })
84
+ );
85
+ return Promise.all(promises);
86
+ }
87
+
88
+ /**
89
+ * Generate designed screenshot
90
+ */
91
+ public async generateDesignedScreenshot(
92
+ content: ScreenshotContent,
93
+ design: ScreenshotDesign
94
+ ): Promise<ScreenshotMetadata> {
95
+ const canvas = await this.renderer.renderDesignedScreenshot(content, design);
96
+ const blob = await this.renderer['canvasRenderer'].exportToBlob(canvas, {
97
+ format: 'png' as ScreenshotFormat,
98
+ });
99
+
100
+ return {
101
+ id: this.generateId(),
102
+ deviceType: design.deviceType,
103
+ dimensions: { width: canvas.width, height: canvas.height },
104
+ format: 'png',
105
+ timestamp: new Date(),
106
+ fileSize: blob.blob.size,
107
+ url: blob.url,
108
+ };
109
+ }
110
+
111
+ /**
112
+ * Export project as ZIP
113
+ */
114
+ public async exportProjectAsZip(
115
+ project: ScreenshotProject
116
+ ): Promise<Blob> {
117
+ const JSZip = (await import('jszip')).default;
118
+ const zip = new JSZip();
119
+ const folder = zip.folder(project.currentLanguage);
120
+
121
+ if (!folder) {
122
+ throw new Error('Failed to create folder in ZIP');
123
+ }
124
+
125
+ // Add metadata if enabled
126
+ if (this.config.export?.includeMetadata) {
127
+ const metadataText = `APP NAME: ${project.appMetadata.appName}
128
+ SUBTITLE: ${project.appMetadata.subtitle}
129
+ DESCRIPTION:
130
+ ${project.appMetadata.description}
131
+
132
+ KEYWORDS: ${project.appMetadata.keywords}
133
+ WHATS NEW:
134
+ ${project.appMetadata.whatsNew}`;
135
+
136
+ folder.file('aso_metadata.txt', metadataText);
137
+ }
138
+
139
+ // Generate screenshots
140
+ for (let i = 0; i < project.screens.length; i++) {
141
+ const screen = project.screens[i];
142
+ const screenshot = await this.generateDesignedScreenshot(screen, project.design);
143
+ const base64Data = screenshot.url.split(',')[1];
144
+ folder.file(
145
+ `screen_${i + 1}_${project.design.deviceType}.png`,
146
+ base64Data,
147
+ { base64: true }
148
+ );
149
+ }
150
+
151
+ return await zip.generateAsync({ type: 'blob' });
152
+ }
153
+
154
+ /**
155
+ * Create project
156
+ */
157
+ public createProject(name: string): ScreenshotProject {
158
+ return {
159
+ id: this.generateId(),
160
+ name,
161
+ design: this.getDefaultDesign(),
162
+ screens: [this.getDefaultScreen()],
163
+ currentLanguage: this.config.defaultLanguage || 'en-US',
164
+ selectedScreenId: '1',
165
+ appMetadata: {
166
+ appName: 'My App',
167
+ subtitle: 'App Description',
168
+ promotionalText: 'Promotional text',
169
+ keywords: 'keyword1, keyword2',
170
+ description: 'App description',
171
+ whatsNew: 'What is new in this version',
172
+ },
173
+ appIcon: null,
174
+ createdAt: new Date(),
175
+ updatedAt: new Date(),
176
+ };
177
+ }
178
+
179
+ /**
180
+ * Get default design
181
+ */
182
+ private getDefaultDesign(): ScreenshotDesign {
183
+ return {
184
+ backgroundColor: '#6366f1',
185
+ backgroundGradientEnd: '#a855f7',
186
+ backgroundImage: null,
187
+ backgroundBlur: 0,
188
+ backgroundOverlayOpacity: 0,
189
+ backgroundPattern: 'none',
190
+ textColor: '#ffffff',
191
+ highlightColor: '#fbbf24',
192
+ textAlign: 'center',
193
+ deviceColor: '#1f2937',
194
+ deviceType: (this.config.device?.defaultDevice || 'iphone-15-pro') as DeviceType,
195
+ frameStyle: 'realistic',
196
+ layout: 'text-top',
197
+ scale: 0.85,
198
+ fontFamily: 'Inter',
199
+ titleFontSize: 60,
200
+ subtitleFontSize: 24,
201
+ titleFontWeight: '900',
202
+ subtitleFontWeight: '500',
203
+ textCase: 'uppercase',
204
+ lineHeight: 0.9,
205
+ letterSpacing: -1,
206
+ rotation: 0,
207
+ rotationX: 0,
208
+ rotationY: 0,
209
+ rotationZ: 0,
210
+ offsetY: 0,
211
+ shadowIntensity: 0.5,
212
+ padding: 40,
213
+ gap: 20,
214
+ isPanoramic: false,
215
+ };
216
+ }
217
+
218
+ /**
219
+ * Get default screen
220
+ */
221
+ private getDefaultScreen(): ScreenshotContent {
222
+ return {
223
+ id: '1',
224
+ title: 'MY *APP*',
225
+ subtitle: 'Your app description here',
226
+ screenshot: null,
227
+ translations: {
228
+ 'en-US': { title: 'MY *APP*', subtitle: 'Your app description here' },
229
+ },
230
+ imageFit: 'cover',
231
+ imageZoom: 1,
232
+ imageAnchorX: 50,
233
+ imageAnchorY: 50,
234
+ };
235
+ }
236
+
237
+ /**
238
+ * Generate unique ID
239
+ */
240
+ private generateId(): string {
241
+ return Math.random().toString(36).substr(2, 9);
242
+ }
243
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Canvas Configuration
3
+ * Canvas operation configuration
4
+ */
5
+
6
+ import type { CanvasFormat, CanvasQuality } from '../types/canvas.types';
7
+
8
+ /**
9
+ * Canvas configuration
10
+ */
11
+ export interface CanvasConfig {
12
+ /** Default export format */
13
+ defaultFormat?: CanvasFormat;
14
+ /** Default quality (0.0 - 1.0) */
15
+ defaultQuality?: CanvasQuality;
16
+ /** Maximum dimension (width or height) */
17
+ maxDimension?: number;
18
+ /** Scale factor for high-resolution exports */
19
+ scale?: number;
20
+ /** Default background color */
21
+ backgroundColor?: string;
22
+ /** Enable CORS for cross-origin images */
23
+ useCORS?: boolean;
24
+ }
25
+
26
+ /**
27
+ * Default canvas configuration
28
+ */
29
+ export const DEFAULT_CANVAS_CONFIG: CanvasConfig = {
30
+ defaultFormat: 'png',
31
+ defaultQuality: 0.9,
32
+ maxDimension: 4096,
33
+ scale: 2,
34
+ backgroundColor: '#ffffff',
35
+ useCORS: true,
36
+ };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Device Configuration
3
+ * Device frame configuration
4
+ */
5
+
6
+ import type { DeviceType } from '../types/screenshot.types';
7
+
8
+ /**
9
+ * Device configuration
10
+ */
11
+ export interface DeviceConfigOption {
12
+ /** Available device types */
13
+ devices: DeviceType[];
14
+ /** Default device type */
15
+ defaultDevice?: DeviceType;
16
+ /** Show device frame */
17
+ showFrame?: boolean;
18
+ /** Frame color */
19
+ frameColor?: string;
20
+ /** Frame thickness in pixels */
21
+ frameThickness?: number;
22
+ }
23
+
24
+ /**
25
+ * Device dimensions presets
26
+ */
27
+ export const DEVICE_DIMENSIONS: Record<DeviceType, { width: number; height: number }> = {
28
+ 'iphone-15-pro': { width: 1290, height: 2796 },
29
+ 'iphone-15': { width: 1179, height: 2556 },
30
+ 'iphone-se': { width: 1080, height: 2340 },
31
+ 'ipad-pro': { width: 2048, height: 2732 },
32
+ 'ipad': { width: 1620, height: 2160 },
33
+ 'android-phone': { width: 1440, height: 3120 },
34
+ 'android-tablet': { width: 2000, height: 2200 },
35
+ 'desktop': { width: 1920, height: 1080 },
36
+ };
37
+
38
+ /**
39
+ * Default device configuration
40
+ */
41
+ export const DEFAULT_DEVICE_CONFIG: DeviceConfigOption = {
42
+ devices: Object.keys(DEVICE_DIMENSIONS) as DeviceType[],
43
+ defaultDevice: 'iphone-15-pro',
44
+ showFrame: true,
45
+ frameColor: '#1f2937',
46
+ frameThickness: 8,
47
+ };