@umituz/web-canvas 1.2.0 → 1.2.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/{chunk-YRC4YPMO.mjs → chunk-7YLVULSN.mjs} +91 -4
- package/dist/domain/index.d.mts +2 -22
- package/dist/domain/index.d.ts +2 -22
- package/dist/index.js +91 -4
- package/dist/index.mjs +1 -1
- package/dist/presentation/index.d.mts +0 -26
- package/dist/presentation/index.d.ts +0 -26
- package/dist/presentation/index.js +91 -4
- package/dist/presentation/index.mjs +1 -1
- package/package.json +1 -1
- package/src/application/index.ts +0 -4
- package/src/application/services/ReportService.ts +0 -22
- package/src/application/services/ScreenshotStudioService.ts +1 -35
- package/src/domain/config/CanvasConfig.ts +0 -16
- package/src/domain/config/DeviceConfig.ts +0 -18
- package/src/domain/config/ScreenshotStudioConfig.ts +0 -29
- package/src/domain/config/index.ts +0 -4
- package/src/domain/index.ts +0 -4
- package/src/domain/types/canvas.types.ts +1 -35
- package/src/domain/types/freehand.types.ts +2 -23
- package/src/domain/types/index.ts +0 -4
- package/src/domain/types/report.types.ts +0 -31
- package/src/domain/types/screenshot.types.ts +1 -65
- package/src/index.ts +0 -12
- package/src/infrastructure/index.ts +0 -4
- package/src/infrastructure/renderers/CanvasRenderer.ts +0 -55
- package/src/infrastructure/renderers/PatternRenderer.ts +0 -30
- package/src/infrastructure/renderers/ScreenshotRenderer.ts +0 -48
- package/src/infrastructure/services/DeviceConfigService.ts +0 -10
- package/src/infrastructure/services/minimalXlsx.ts +0 -11
- package/src/presentation/hooks/useCanvasExport.ts +2 -22
- package/src/presentation/hooks/useFreehandCanvas.ts +102 -40
- package/src/presentation/hooks/useReportExport.ts +0 -12
- package/src/presentation/hooks/useScreenshotStudio.ts +1 -45
- package/src/presentation/index.ts +0 -4
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Screenshot Types
|
|
3
|
-
* Screenshot generation and device frame types
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Device type
|
|
8
|
-
*/
|
|
1
|
+
|
|
9
2
|
export type DeviceType =
|
|
10
3
|
| 'iphone-15-pro'
|
|
11
4
|
| 'iphone-15'
|
|
@@ -16,9 +9,6 @@ export type DeviceType =
|
|
|
16
9
|
| 'android-tablet'
|
|
17
10
|
| 'desktop';
|
|
18
11
|
|
|
19
|
-
/**
|
|
20
|
-
* Device type enum (for backward compatibility)
|
|
21
|
-
*/
|
|
22
12
|
export const DeviceTypeEnum = {
|
|
23
13
|
IPHONE_15_PRO: 'iphone-15-pro',
|
|
24
14
|
IPHONE_15: 'iphone-15',
|
|
@@ -30,37 +20,22 @@ export const DeviceTypeEnum = {
|
|
|
30
20
|
DESKTOP: 'desktop',
|
|
31
21
|
} as const;
|
|
32
22
|
|
|
33
|
-
/**
|
|
34
|
-
* Frame style options
|
|
35
|
-
*/
|
|
36
23
|
export type FrameStyle = 'realistic' | 'minimal' | 'none';
|
|
37
24
|
|
|
38
|
-
/**
|
|
39
|
-
* Frame style enum (for backward compatibility)
|
|
40
|
-
*/
|
|
41
25
|
export const FrameStyleEnum = {
|
|
42
26
|
REALISTIC: 'realistic',
|
|
43
27
|
MINIMAL: 'minimal',
|
|
44
28
|
NONE: 'none',
|
|
45
29
|
} as const;
|
|
46
30
|
|
|
47
|
-
/**
|
|
48
|
-
* Layout style options
|
|
49
|
-
*/
|
|
50
31
|
export type LayoutStyle = 'text-top' | 'text-bottom' | 'text-overlay';
|
|
51
32
|
|
|
52
|
-
/**
|
|
53
|
-
* Layout style enum (for backward compatibility)
|
|
54
|
-
*/
|
|
55
33
|
export const LayoutStyleEnum = {
|
|
56
34
|
TEXT_TOP: 'text-top',
|
|
57
35
|
TEXT_BOTTOM: 'text-bottom',
|
|
58
36
|
TEXT_OVERLAY: 'text-overlay',
|
|
59
37
|
} as const;
|
|
60
38
|
|
|
61
|
-
/**
|
|
62
|
-
* Background pattern options
|
|
63
|
-
*/
|
|
64
39
|
export type BackgroundPattern =
|
|
65
40
|
| 'none'
|
|
66
41
|
| 'dots'
|
|
@@ -69,9 +44,6 @@ export type BackgroundPattern =
|
|
|
69
44
|
| 'waves'
|
|
70
45
|
| 'checkers';
|
|
71
46
|
|
|
72
|
-
/**
|
|
73
|
-
* Background pattern enum (for backward compatibility)
|
|
74
|
-
*/
|
|
75
47
|
export const BackgroundPatternEnum = {
|
|
76
48
|
NONE: 'none',
|
|
77
49
|
DOTS: 'dots',
|
|
@@ -81,37 +53,22 @@ export const BackgroundPatternEnum = {
|
|
|
81
53
|
CHECKERS: 'checkers',
|
|
82
54
|
} as const;
|
|
83
55
|
|
|
84
|
-
/**
|
|
85
|
-
* Screenshot format
|
|
86
|
-
*/
|
|
87
56
|
export type ScreenshotFormat = 'png' | 'jpeg' | 'webp';
|
|
88
57
|
|
|
89
|
-
/**
|
|
90
|
-
* Screenshot format enum (for backward compatibility)
|
|
91
|
-
*/
|
|
92
58
|
export const ScreenshotFormatEnum = {
|
|
93
59
|
PNG: 'png',
|
|
94
60
|
JPEG: 'jpeg',
|
|
95
61
|
WEBP: 'webp',
|
|
96
62
|
} as const;
|
|
97
63
|
|
|
98
|
-
/**
|
|
99
|
-
* Language code
|
|
100
|
-
*/
|
|
101
64
|
export type Language = string;
|
|
102
65
|
|
|
103
|
-
/**
|
|
104
|
-
* Device dimensions
|
|
105
|
-
*/
|
|
106
66
|
export interface DeviceDimensions {
|
|
107
67
|
width: number;
|
|
108
68
|
height: number;
|
|
109
69
|
scale?: number;
|
|
110
70
|
}
|
|
111
71
|
|
|
112
|
-
/**
|
|
113
|
-
* Device configuration
|
|
114
|
-
*/
|
|
115
72
|
export interface DeviceConfig {
|
|
116
73
|
type: DeviceType;
|
|
117
74
|
name: string;
|
|
@@ -123,9 +80,6 @@ export interface DeviceConfig {
|
|
|
123
80
|
frameThickness?: number;
|
|
124
81
|
}
|
|
125
82
|
|
|
126
|
-
/**
|
|
127
|
-
* Screenshot content
|
|
128
|
-
*/
|
|
129
83
|
export interface ScreenshotContent {
|
|
130
84
|
id: string;
|
|
131
85
|
title: string;
|
|
@@ -138,9 +92,6 @@ export interface ScreenshotContent {
|
|
|
138
92
|
imageAnchorY?: number;
|
|
139
93
|
}
|
|
140
94
|
|
|
141
|
-
/**
|
|
142
|
-
* Screenshot design
|
|
143
|
-
*/
|
|
144
95
|
export interface ScreenshotDesign {
|
|
145
96
|
backgroundColor: string;
|
|
146
97
|
backgroundGradientEnd?: string | null;
|
|
@@ -175,9 +126,6 @@ export interface ScreenshotDesign {
|
|
|
175
126
|
isPanoramic?: boolean;
|
|
176
127
|
}
|
|
177
128
|
|
|
178
|
-
/**
|
|
179
|
-
* Screenshot metadata
|
|
180
|
-
*/
|
|
181
129
|
export interface ScreenshotMetadata {
|
|
182
130
|
id: string;
|
|
183
131
|
deviceType: DeviceType;
|
|
@@ -188,9 +136,6 @@ export interface ScreenshotMetadata {
|
|
|
188
136
|
url: string;
|
|
189
137
|
}
|
|
190
138
|
|
|
191
|
-
/**
|
|
192
|
-
* Screenshot generation options
|
|
193
|
-
*/
|
|
194
139
|
export interface ScreenshotGenerationOptions {
|
|
195
140
|
deviceType: DeviceType;
|
|
196
141
|
format?: ScreenshotFormat;
|
|
@@ -198,9 +143,6 @@ export interface ScreenshotGenerationOptions {
|
|
|
198
143
|
customDimensions?: DeviceDimensions;
|
|
199
144
|
}
|
|
200
145
|
|
|
201
|
-
/**
|
|
202
|
-
* Screenshot template
|
|
203
|
-
*/
|
|
204
146
|
export interface ScreenshotTemplate {
|
|
205
147
|
id: string;
|
|
206
148
|
name: string;
|
|
@@ -209,9 +151,6 @@ export interface ScreenshotTemplate {
|
|
|
209
151
|
thumbnail?: string;
|
|
210
152
|
}
|
|
211
153
|
|
|
212
|
-
/**
|
|
213
|
-
* App Store metadata
|
|
214
|
-
*/
|
|
215
154
|
export interface AppStoreMetadata {
|
|
216
155
|
appName: string;
|
|
217
156
|
subtitle: string;
|
|
@@ -221,9 +160,6 @@ export interface AppStoreMetadata {
|
|
|
221
160
|
whatsNew: string;
|
|
222
161
|
}
|
|
223
162
|
|
|
224
|
-
/**
|
|
225
|
-
* Screenshot project
|
|
226
|
-
*/
|
|
227
163
|
export interface ScreenshotProject {
|
|
228
164
|
id: string;
|
|
229
165
|
name: string;
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @umituz/web-canvas
|
|
3
|
-
* Comprehensive canvas and screenshot generation library
|
|
4
|
-
*/
|
|
5
1
|
|
|
6
|
-
// Domain exports
|
|
7
2
|
export type {
|
|
8
|
-
// Canvas types
|
|
9
3
|
CanvasFormat,
|
|
10
4
|
CanvasQuality,
|
|
11
5
|
CanvasDimensions,
|
|
@@ -17,7 +11,6 @@ export type {
|
|
|
17
11
|
CanvasResult,
|
|
18
12
|
CanvasOperation,
|
|
19
13
|
|
|
20
|
-
// Screenshot types
|
|
21
14
|
DeviceType,
|
|
22
15
|
FrameStyle,
|
|
23
16
|
LayoutStyle,
|
|
@@ -34,7 +27,6 @@ export type {
|
|
|
34
27
|
AppStoreMetadata,
|
|
35
28
|
ScreenshotProject,
|
|
36
29
|
|
|
37
|
-
// Report types
|
|
38
30
|
ReportItemType,
|
|
39
31
|
ReportItem,
|
|
40
32
|
ReportSummary,
|
|
@@ -45,7 +37,6 @@ export type {
|
|
|
45
37
|
CSVExportOptions,
|
|
46
38
|
ReportExportResult,
|
|
47
39
|
|
|
48
|
-
// Freehand types
|
|
49
40
|
FreehandPoint,
|
|
50
41
|
FreehandStroke,
|
|
51
42
|
UseFreehandCanvasOptions,
|
|
@@ -72,7 +63,6 @@ export {
|
|
|
72
63
|
DEFAULT_SCREENSHOT_STUDIO_CONFIG,
|
|
73
64
|
} from './domain/config/ScreenshotStudioConfig';
|
|
74
65
|
|
|
75
|
-
// Infrastructure exports
|
|
76
66
|
export { CanvasRenderer } from './infrastructure/renderers/CanvasRenderer';
|
|
77
67
|
export { PatternRenderer } from './infrastructure/renderers/PatternRenderer';
|
|
78
68
|
export {
|
|
@@ -82,13 +72,11 @@ export {
|
|
|
82
72
|
DeviceConfigService,
|
|
83
73
|
} from './infrastructure/services/DeviceConfigService';
|
|
84
74
|
|
|
85
|
-
// Application exports
|
|
86
75
|
export {
|
|
87
76
|
ScreenshotStudioService,
|
|
88
77
|
} from './application/services/ScreenshotStudioService';
|
|
89
78
|
export { ReportService } from './application/services/ReportService';
|
|
90
79
|
|
|
91
|
-
// Presentation exports
|
|
92
80
|
export {
|
|
93
81
|
useScreenshotStudio,
|
|
94
82
|
type UseScreenshotStudioOptions,
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canvas Renderer
|
|
3
|
-
* Core canvas rendering operations
|
|
4
|
-
*/
|
|
5
1
|
|
|
6
2
|
import type {
|
|
7
3
|
CanvasDimensions,
|
|
@@ -20,9 +16,6 @@ export class CanvasRenderer {
|
|
|
20
16
|
this.imageCache = new Map();
|
|
21
17
|
}
|
|
22
18
|
|
|
23
|
-
/**
|
|
24
|
-
* Create a new canvas element
|
|
25
|
-
*/
|
|
26
19
|
public createCanvas(dimensions: CanvasDimensions): HTMLCanvasElement {
|
|
27
20
|
const canvas = document.createElement('canvas');
|
|
28
21
|
canvas.width = dimensions.width;
|
|
@@ -30,18 +23,12 @@ export class CanvasRenderer {
|
|
|
30
23
|
return canvas;
|
|
31
24
|
}
|
|
32
25
|
|
|
33
|
-
/**
|
|
34
|
-
* Get canvas 2D context
|
|
35
|
-
*/
|
|
36
26
|
public getContext(
|
|
37
27
|
canvas: HTMLCanvasElement
|
|
38
28
|
): CanvasRenderingContext2D | null {
|
|
39
29
|
return canvas.getContext('2d');
|
|
40
30
|
}
|
|
41
31
|
|
|
42
|
-
/**
|
|
43
|
-
* Apply context configuration
|
|
44
|
-
*/
|
|
45
32
|
public configureContext(
|
|
46
33
|
ctx: CanvasRenderingContext2D,
|
|
47
34
|
config: CanvasContextConfig
|
|
@@ -75,9 +62,6 @@ export class CanvasRenderer {
|
|
|
75
62
|
}
|
|
76
63
|
}
|
|
77
64
|
|
|
78
|
-
/**
|
|
79
|
-
* Clear canvas
|
|
80
|
-
*/
|
|
81
65
|
public clearCanvas(
|
|
82
66
|
ctx: CanvasRenderingContext2D,
|
|
83
67
|
dimensions: CanvasDimensions
|
|
@@ -85,9 +69,6 @@ export class CanvasRenderer {
|
|
|
85
69
|
ctx.clearRect(0, 0, dimensions.width, dimensions.height);
|
|
86
70
|
}
|
|
87
71
|
|
|
88
|
-
/**
|
|
89
|
-
* Fill rectangle
|
|
90
|
-
*/
|
|
91
72
|
public fillRect(
|
|
92
73
|
ctx: CanvasRenderingContext2D,
|
|
93
74
|
x: number,
|
|
@@ -102,9 +83,6 @@ export class CanvasRenderer {
|
|
|
102
83
|
ctx.fillRect(x, y, width, height);
|
|
103
84
|
}
|
|
104
85
|
|
|
105
|
-
/**
|
|
106
|
-
* Stroke rectangle
|
|
107
|
-
*/
|
|
108
86
|
public strokeRect(
|
|
109
87
|
ctx: CanvasRenderingContext2D,
|
|
110
88
|
x: number,
|
|
@@ -123,9 +101,6 @@ export class CanvasRenderer {
|
|
|
123
101
|
ctx.strokeRect(x, y, width, height);
|
|
124
102
|
}
|
|
125
103
|
|
|
126
|
-
/**
|
|
127
|
-
* Draw text
|
|
128
|
-
*/
|
|
129
104
|
public drawText(
|
|
130
105
|
ctx: CanvasRenderingContext2D,
|
|
131
106
|
text: string,
|
|
@@ -139,9 +114,6 @@ export class CanvasRenderer {
|
|
|
139
114
|
ctx.fillText(text, x, y);
|
|
140
115
|
}
|
|
141
116
|
|
|
142
|
-
/**
|
|
143
|
-
* Draw image
|
|
144
|
-
*/
|
|
145
117
|
public async drawImage(
|
|
146
118
|
ctx: CanvasRenderingContext2D,
|
|
147
119
|
imageSource: string | HTMLImageElement,
|
|
@@ -165,11 +137,7 @@ export class CanvasRenderer {
|
|
|
165
137
|
}
|
|
166
138
|
}
|
|
167
139
|
|
|
168
|
-
/**
|
|
169
|
-
* Load image from URL with caching
|
|
170
|
-
*/
|
|
171
140
|
private loadImage(url: string): Promise<HTMLImageElement> {
|
|
172
|
-
// Check cache first
|
|
173
141
|
if (this.imageCache.has(url)) {
|
|
174
142
|
return Promise.resolve(this.imageCache.get(url)!);
|
|
175
143
|
}
|
|
@@ -180,7 +148,6 @@ export class CanvasRenderer {
|
|
|
180
148
|
img.crossOrigin = 'anonymous';
|
|
181
149
|
}
|
|
182
150
|
img.onload = () => {
|
|
183
|
-
// Cache the loaded image
|
|
184
151
|
this.imageCache.set(url, img);
|
|
185
152
|
resolve(img);
|
|
186
153
|
};
|
|
@@ -189,23 +156,14 @@ export class CanvasRenderer {
|
|
|
189
156
|
});
|
|
190
157
|
}
|
|
191
158
|
|
|
192
|
-
/**
|
|
193
|
-
* Clear image cache to free memory
|
|
194
|
-
*/
|
|
195
159
|
public clearImageCache(): void {
|
|
196
160
|
this.imageCache.clear();
|
|
197
161
|
}
|
|
198
162
|
|
|
199
|
-
/**
|
|
200
|
-
* Get cache size for monitoring
|
|
201
|
-
*/
|
|
202
163
|
public getCacheSize(): number {
|
|
203
164
|
return this.imageCache.size;
|
|
204
165
|
}
|
|
205
166
|
|
|
206
|
-
/**
|
|
207
|
-
* Create gradient
|
|
208
|
-
*/
|
|
209
167
|
public createLinearGradient(
|
|
210
168
|
ctx: CanvasRenderingContext2D,
|
|
211
169
|
x1: number,
|
|
@@ -221,9 +179,6 @@ export class CanvasRenderer {
|
|
|
221
179
|
return gradient;
|
|
222
180
|
}
|
|
223
181
|
|
|
224
|
-
/**
|
|
225
|
-
* Export canvas to blob
|
|
226
|
-
*/
|
|
227
182
|
public async exportToBlob(
|
|
228
183
|
canvas: HTMLCanvasElement,
|
|
229
184
|
options: CanvasExportOptions = {}
|
|
@@ -232,7 +187,6 @@ export class CanvasRenderer {
|
|
|
232
187
|
const quality = options.quality || this.config.defaultQuality;
|
|
233
188
|
const scale = options.scale || this.config.scale;
|
|
234
189
|
|
|
235
|
-
// Scale canvas if needed
|
|
236
190
|
const scaledCanvas = (scale || 1) !== 1 ? this.scaleCanvas(canvas, scale || 1) : canvas;
|
|
237
191
|
|
|
238
192
|
const mimeType = `image/${format || 'png'}`;
|
|
@@ -262,9 +216,6 @@ export class CanvasRenderer {
|
|
|
262
216
|
};
|
|
263
217
|
}
|
|
264
218
|
|
|
265
|
-
/**
|
|
266
|
-
* Export canvas to data URL
|
|
267
|
-
*/
|
|
268
219
|
public exportToDataURL(
|
|
269
220
|
canvas: HTMLCanvasElement,
|
|
270
221
|
format?: string,
|
|
@@ -275,9 +226,6 @@ export class CanvasRenderer {
|
|
|
275
226
|
return canvas.toDataURL(mimeType, q);
|
|
276
227
|
}
|
|
277
228
|
|
|
278
|
-
/**
|
|
279
|
-
* Scale canvas
|
|
280
|
-
*/
|
|
281
229
|
private scaleCanvas(
|
|
282
230
|
canvas: HTMLCanvasElement,
|
|
283
231
|
scale: number
|
|
@@ -296,9 +244,6 @@ export class CanvasRenderer {
|
|
|
296
244
|
return scaled;
|
|
297
245
|
}
|
|
298
246
|
|
|
299
|
-
/**
|
|
300
|
-
* Clone canvas
|
|
301
|
-
*/
|
|
302
247
|
public cloneCanvas(canvas: HTMLCanvasElement): HTMLCanvasElement {
|
|
303
248
|
const clone = document.createElement('canvas');
|
|
304
249
|
clone.width = canvas.width;
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pattern Renderer
|
|
3
|
-
* Background pattern rendering operations
|
|
4
|
-
*/
|
|
5
1
|
|
|
6
2
|
import type { CanvasDimensions } from '../../domain/types/canvas.types';
|
|
7
3
|
import type { BackgroundPattern } from '../../domain/types/screenshot.types';
|
|
@@ -10,9 +6,6 @@ export class PatternRenderer {
|
|
|
10
6
|
private patternCanvasCache: Map<string, HTMLCanvasElement> = new Map();
|
|
11
7
|
private readonly MAX_CACHE_SIZE = 10;
|
|
12
8
|
|
|
13
|
-
/**
|
|
14
|
-
* Render pattern on canvas
|
|
15
|
-
*/
|
|
16
9
|
public renderPattern(
|
|
17
10
|
ctx: CanvasRenderingContext2D,
|
|
18
11
|
pattern: BackgroundPattern,
|
|
@@ -45,16 +38,10 @@ export class PatternRenderer {
|
|
|
45
38
|
ctx.restore();
|
|
46
39
|
}
|
|
47
40
|
|
|
48
|
-
/**
|
|
49
|
-
* Clear pattern cache to free memory
|
|
50
|
-
*/
|
|
51
41
|
public clearCache(): void {
|
|
52
42
|
this.patternCanvasCache.clear();
|
|
53
43
|
}
|
|
54
44
|
|
|
55
|
-
/**
|
|
56
|
-
* Render dot pattern - optimized with batch rendering
|
|
57
|
-
*/
|
|
58
45
|
private renderDotPattern(
|
|
59
46
|
ctx: CanvasRenderingContext2D,
|
|
60
47
|
dimensions: CanvasDimensions,
|
|
@@ -64,7 +51,6 @@ export class PatternRenderer {
|
|
|
64
51
|
const spacing = 30;
|
|
65
52
|
const radius = 2;
|
|
66
53
|
|
|
67
|
-
// Batch rendering for better performance
|
|
68
54
|
ctx.beginPath();
|
|
69
55
|
for (let x = spacing; x < dimensions.width; x += spacing) {
|
|
70
56
|
for (let y = spacing; y < dimensions.height; y += spacing) {
|
|
@@ -75,9 +61,6 @@ export class PatternRenderer {
|
|
|
75
61
|
ctx.fill();
|
|
76
62
|
}
|
|
77
63
|
|
|
78
|
-
/**
|
|
79
|
-
* Render grid pattern - optimized with single path
|
|
80
|
-
*/
|
|
81
64
|
private renderGridPattern(
|
|
82
65
|
ctx: CanvasRenderingContext2D,
|
|
83
66
|
dimensions: CanvasDimensions,
|
|
@@ -89,13 +72,11 @@ export class PatternRenderer {
|
|
|
89
72
|
|
|
90
73
|
ctx.beginPath();
|
|
91
74
|
|
|
92
|
-
// Vertical lines
|
|
93
75
|
for (let x = 0; x <= dimensions.width; x += spacing) {
|
|
94
76
|
ctx.moveTo(x, 0);
|
|
95
77
|
ctx.lineTo(x, dimensions.height);
|
|
96
78
|
}
|
|
97
79
|
|
|
98
|
-
// Horizontal lines
|
|
99
80
|
for (let y = 0; y <= dimensions.height; y += spacing) {
|
|
100
81
|
ctx.moveTo(0, y);
|
|
101
82
|
ctx.lineTo(dimensions.width, y);
|
|
@@ -104,9 +85,6 @@ export class PatternRenderer {
|
|
|
104
85
|
ctx.stroke();
|
|
105
86
|
}
|
|
106
87
|
|
|
107
|
-
/**
|
|
108
|
-
* Render line pattern - optimized with single path
|
|
109
|
-
*/
|
|
110
88
|
private renderLinePattern(
|
|
111
89
|
ctx: CanvasRenderingContext2D,
|
|
112
90
|
dimensions: CanvasDimensions,
|
|
@@ -118,7 +96,6 @@ export class PatternRenderer {
|
|
|
118
96
|
|
|
119
97
|
ctx.beginPath();
|
|
120
98
|
|
|
121
|
-
// Draw all lines in a single path
|
|
122
99
|
for (let y = spacing; y < dimensions.height; y += spacing) {
|
|
123
100
|
ctx.moveTo(0, y);
|
|
124
101
|
ctx.lineTo(dimensions.width, y);
|
|
@@ -127,9 +104,6 @@ export class PatternRenderer {
|
|
|
127
104
|
ctx.stroke();
|
|
128
105
|
}
|
|
129
106
|
|
|
130
|
-
/**
|
|
131
|
-
* Render wave pattern - optimized with pre-calculated values
|
|
132
|
-
*/
|
|
133
107
|
private renderWavePattern(
|
|
134
108
|
ctx: CanvasRenderingContext2D,
|
|
135
109
|
dimensions: CanvasDimensions,
|
|
@@ -145,7 +119,6 @@ export class PatternRenderer {
|
|
|
145
119
|
for (let y = spacing; y < dimensions.height; y += spacing) {
|
|
146
120
|
ctx.beginPath();
|
|
147
121
|
|
|
148
|
-
// Pre-calculate wave points and use more efficient path drawing
|
|
149
122
|
const startX = 0;
|
|
150
123
|
const startY = y + Math.sin(startX * frequency) * amplitude;
|
|
151
124
|
ctx.moveTo(startX, startY);
|
|
@@ -159,9 +132,6 @@ export class PatternRenderer {
|
|
|
159
132
|
}
|
|
160
133
|
}
|
|
161
134
|
|
|
162
|
-
/**
|
|
163
|
-
* Render checker pattern
|
|
164
|
-
*/
|
|
165
135
|
private renderCheckerPattern(
|
|
166
136
|
ctx: CanvasRenderingContext2D,
|
|
167
137
|
dimensions: CanvasDimensions,
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Screenshot Renderer
|
|
3
|
-
* Device frame and screenshot rendering operations
|
|
4
|
-
*/
|
|
5
1
|
|
|
6
2
|
import type {
|
|
7
3
|
CanvasDimensions,
|
|
@@ -31,18 +27,12 @@ export class ScreenshotRenderer {
|
|
|
31
27
|
this.deviceConfigService = DeviceConfigService.getInstance();
|
|
32
28
|
}
|
|
33
29
|
|
|
34
|
-
/**
|
|
35
|
-
* Clear render cache to free memory
|
|
36
|
-
*/
|
|
37
30
|
public clearCache(): void {
|
|
38
31
|
this.renderCache.clear();
|
|
39
32
|
this.canvasRenderer.clearImageCache?.();
|
|
40
33
|
this.patternRenderer.clearCache?.();
|
|
41
34
|
}
|
|
42
35
|
|
|
43
|
-
/**
|
|
44
|
-
* Render device frame
|
|
45
|
-
*/
|
|
46
36
|
public renderDeviceFrame(
|
|
47
37
|
ctx: CanvasRenderingContext2D,
|
|
48
38
|
dimensions: CanvasDimensions,
|
|
@@ -72,9 +62,6 @@ export class ScreenshotRenderer {
|
|
|
72
62
|
}
|
|
73
63
|
}
|
|
74
64
|
|
|
75
|
-
/**
|
|
76
|
-
* Render realistic device frame
|
|
77
|
-
*/
|
|
78
65
|
private renderRealisticFrame(
|
|
79
66
|
ctx: CanvasRenderingContext2D,
|
|
80
67
|
dimensions: CanvasDimensions,
|
|
@@ -91,9 +78,6 @@ export class ScreenshotRenderer {
|
|
|
91
78
|
);
|
|
92
79
|
}
|
|
93
80
|
|
|
94
|
-
/**
|
|
95
|
-
* Render minimal device frame
|
|
96
|
-
*/
|
|
97
81
|
private renderMinimalFrame(
|
|
98
82
|
ctx: CanvasRenderingContext2D,
|
|
99
83
|
dimensions: CanvasDimensions,
|
|
@@ -105,9 +89,6 @@ export class ScreenshotRenderer {
|
|
|
105
89
|
ctx.strokeRect(0, 0, dimensions.width, dimensions.height);
|
|
106
90
|
}
|
|
107
91
|
|
|
108
|
-
/**
|
|
109
|
-
* Render device notch
|
|
110
|
-
*/
|
|
111
92
|
private renderNotch(
|
|
112
93
|
ctx: CanvasRenderingContext2D,
|
|
113
94
|
dimensions: CanvasDimensions
|
|
@@ -118,15 +99,11 @@ export class ScreenshotRenderer {
|
|
|
118
99
|
ctx.fill();
|
|
119
100
|
}
|
|
120
101
|
|
|
121
|
-
/**
|
|
122
|
-
* Render background - optimized
|
|
123
|
-
*/
|
|
124
102
|
public renderBackground(
|
|
125
103
|
ctx: CanvasRenderingContext2D,
|
|
126
104
|
design: ScreenshotDesign,
|
|
127
105
|
dimensions: CanvasDimensions
|
|
128
106
|
): void {
|
|
129
|
-
// Fill background
|
|
130
107
|
if (design.backgroundGradientEnd) {
|
|
131
108
|
const gradient = this.canvasRenderer.createLinearGradient(
|
|
132
109
|
ctx,
|
|
@@ -146,7 +123,6 @@ export class ScreenshotRenderer {
|
|
|
146
123
|
|
|
147
124
|
ctx.fillRect(0, 0, dimensions.width, dimensions.height);
|
|
148
125
|
|
|
149
|
-
// Render pattern if specified (and not none)
|
|
150
126
|
if (design.backgroundPattern && design.backgroundPattern !== 'none') {
|
|
151
127
|
this.patternRenderer.renderPattern(
|
|
152
128
|
ctx,
|
|
@@ -156,9 +132,6 @@ export class ScreenshotRenderer {
|
|
|
156
132
|
}
|
|
157
133
|
}
|
|
158
134
|
|
|
159
|
-
/**
|
|
160
|
-
* Render text content
|
|
161
|
-
*/
|
|
162
135
|
public renderTextContent(
|
|
163
136
|
ctx: CanvasRenderingContext2D,
|
|
164
137
|
content: ScreenshotContent,
|
|
@@ -200,9 +173,6 @@ export class ScreenshotRenderer {
|
|
|
200
173
|
);
|
|
201
174
|
}
|
|
202
175
|
|
|
203
|
-
/**
|
|
204
|
-
* Format text case
|
|
205
|
-
*/
|
|
206
176
|
private formatText(
|
|
207
177
|
text: string,
|
|
208
178
|
textCase: 'uppercase' | 'lowercase' | 'none' = 'none'
|
|
@@ -217,9 +187,6 @@ export class ScreenshotRenderer {
|
|
|
217
187
|
}
|
|
218
188
|
}
|
|
219
189
|
|
|
220
|
-
/**
|
|
221
|
-
* Render screenshot image
|
|
222
|
-
*/
|
|
223
190
|
public async renderScreenshotImage(
|
|
224
191
|
ctx: CanvasRenderingContext2D,
|
|
225
192
|
imageUrl: string,
|
|
@@ -233,7 +200,6 @@ export class ScreenshotRenderer {
|
|
|
233
200
|
);
|
|
234
201
|
if (!deviceConfig) return;
|
|
235
202
|
|
|
236
|
-
// Calculate screenshot area (inside device frame)
|
|
237
203
|
const frameThickness = deviceConfig.frameThickness || 8;
|
|
238
204
|
const padding = 60 + frameThickness;
|
|
239
205
|
const screenshotWidth = dimensions.width - padding * 2;
|
|
@@ -253,9 +219,6 @@ export class ScreenshotRenderer {
|
|
|
253
219
|
}
|
|
254
220
|
}
|
|
255
221
|
|
|
256
|
-
/**
|
|
257
|
-
* Render complete screenshot
|
|
258
|
-
*/
|
|
259
222
|
public async renderDesignedScreenshot(
|
|
260
223
|
content: ScreenshotContent,
|
|
261
224
|
design: ScreenshotDesign
|
|
@@ -274,18 +237,14 @@ export class ScreenshotRenderer {
|
|
|
274
237
|
throw new Error('Failed to get canvas context');
|
|
275
238
|
}
|
|
276
239
|
|
|
277
|
-
// Render background
|
|
278
240
|
this.renderBackground(ctx, design, dimensions);
|
|
279
241
|
|
|
280
|
-
// Render screenshot image if available
|
|
281
242
|
if (content.screenshot) {
|
|
282
243
|
await this.renderScreenshotImage(ctx, content.screenshot, design, dimensions);
|
|
283
244
|
}
|
|
284
245
|
|
|
285
|
-
// Render text content
|
|
286
246
|
this.renderTextContent(ctx, content, design, dimensions);
|
|
287
247
|
|
|
288
|
-
// Render device frame
|
|
289
248
|
this.renderDeviceFrame(
|
|
290
249
|
ctx,
|
|
291
250
|
dimensions,
|
|
@@ -297,18 +256,13 @@ export class ScreenshotRenderer {
|
|
|
297
256
|
return canvas;
|
|
298
257
|
}
|
|
299
258
|
|
|
300
|
-
/**
|
|
301
|
-
* Render placeholder content
|
|
302
|
-
*/
|
|
303
259
|
public renderPlaceholderContent(
|
|
304
260
|
ctx: CanvasRenderingContext2D,
|
|
305
261
|
dimensions: CanvasDimensions,
|
|
306
262
|
deviceType: DeviceType
|
|
307
263
|
): void {
|
|
308
|
-
// Background
|
|
309
264
|
this.canvasRenderer.fillRect(ctx, 0, 0, dimensions.width, dimensions.height, '#ffffff');
|
|
310
265
|
|
|
311
|
-
// Header area
|
|
312
266
|
this.canvasRenderer.fillRect(ctx, 0, 0, dimensions.width, 60, '#f3f4f6');
|
|
313
267
|
this.canvasRenderer.fillRect(
|
|
314
268
|
ctx,
|
|
@@ -319,7 +273,6 @@ export class ScreenshotRenderer {
|
|
|
319
273
|
'#f3f4f6'
|
|
320
274
|
);
|
|
321
275
|
|
|
322
|
-
// Placeholder content blocks
|
|
323
276
|
ctx.fillStyle = '#e5e7eb';
|
|
324
277
|
for (let i = 0; i < 5; i++) {
|
|
325
278
|
const y = 80 + i * 120;
|
|
@@ -329,7 +282,6 @@ export class ScreenshotRenderer {
|
|
|
329
282
|
}
|
|
330
283
|
}
|
|
331
284
|
|
|
332
|
-
// Device frame
|
|
333
285
|
const deviceConfig = this.deviceConfigService.getDeviceConfig(deviceType);
|
|
334
286
|
if (deviceConfig) {
|
|
335
287
|
this.renderDeviceFrame(
|