@qr-styled/browser 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Luis Manuel Yerena Sosa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,341 @@
1
+ # @qr-styled/browser
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@qr-styled/browser.svg)](https://www.npmjs.com/package/@qr-styled/browser)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ A professional browser QR code generator library with advanced styling options including **gradients**, **rounded modules**, **logo support**, **specialized QR types** (vCard, WiFi, Email, SMS, Geo), and **eye customization**.
7
+
8
+ ## Features
9
+
10
+ ✅ **Browser-native** - Uses HTML5 Canvas API
11
+ ✅ **PNG/JPEG export** - Download or convert to Blob/DataURL
12
+ ✅ **SVG support** - Vector graphics export
13
+ ✅ **Custom colors & gradients** - Multi-color linear gradients
14
+ ✅ **Logo integration** - Circle/square shapes, customizable size
15
+ ✅ **Eye customization** - Custom colors and corner radius
16
+ ✅ **Rounded modules** - Smooth, professional appearance
17
+ ✅ **Specialized QR types** - vCard, WiFi, Email, SMS, Geo
18
+ ✅ **TypeScript** - Full type safety
19
+ ✅ **Zero dependencies** - Only `qrcode` library
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install @qr-styled/browser
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ```typescript
30
+ import { QRGenerator } from '@qr-styled/browser';
31
+
32
+ const qr = new QRGenerator({
33
+ url: 'https://example.com',
34
+ size: 400,
35
+ foregroundColor: '#1a73e8',
36
+ backgroundColor: '#ffffff',
37
+ rounded: true
38
+ });
39
+
40
+ // Append to DOM
41
+ await qr.appendTo(document.body);
42
+
43
+ // Download as PNG
44
+ await qr.download('qrcode.png');
45
+
46
+ // Get as Blob
47
+ const blob = await qr.generateToBlob();
48
+
49
+ // Get as Data URL
50
+ const dataURL = await qr.generateToDataURL();
51
+ ```
52
+
53
+ ## API Reference
54
+
55
+ ### Constructor
56
+
57
+ ```typescript
58
+ new QRGenerator(options: QROptions)
59
+ ```
60
+
61
+ ### Methods
62
+
63
+ #### `generate(): Promise<HTMLCanvasElement>`
64
+ Generates and returns the QR code canvas element.
65
+
66
+ #### `appendTo(element: HTMLElement): Promise<HTMLCanvasElement>`
67
+ Generates the QR code and appends it to the specified DOM element.
68
+
69
+ #### `generateToDataURL(format?: 'png' | 'jpeg'): Promise<string>`
70
+ Generates a data URL of the QR code.
71
+
72
+ #### `generateToBlob(format?: 'png' | 'jpeg'): Promise<Blob>`
73
+ Generates a Blob of the QR code image.
74
+
75
+ #### `download(filename?: string): Promise<void>`
76
+ Generates and downloads the QR code as an image file.
77
+
78
+ #### `generateToSVG(): Promise<string>`
79
+ Generates an SVG string of the QR code.
80
+
81
+ #### `downloadSVG(filename?: string): Promise<void>`
82
+ Generates and downloads the QR code as an SVG file.
83
+
84
+ #### `updateOptions(options: Partial<QROptions>): void`
85
+ Updates the generator options.
86
+
87
+ ### Helper Functions
88
+
89
+ ```typescript
90
+ // Quick generation
91
+ import { generateQR, generateQRToElement, generateQRAndDownload } from '@qr-styled/browser';
92
+
93
+ // Generate canvas
94
+ const canvas = await generateQR({ url: 'https://example.com' });
95
+
96
+ // Generate and append to DOM
97
+ const canvas = await generateQRToElement({ url: 'https://example.com' }, document.body);
98
+
99
+ // Generate and download
100
+ await generateQRAndDownload({ url: 'https://example.com' }, 'qrcode.png');
101
+ ```
102
+
103
+ ## Options
104
+
105
+ ### Basic Options
106
+
107
+ | Option | Type | Default | Description |
108
+ |--------|------|---------|-------------|
109
+ | `url` | `string` | - | URL or text content |
110
+ | `type` | `QRDataType` | `'url'` | Type of QR data |
111
+ | `size` | `number` | `400` | Canvas size in pixels |
112
+ | `foregroundColor` | `string` | `'#000000'` | QR code color |
113
+ | `backgroundColor` | `string` | `'#ffffff'` | Background color |
114
+ | `padding` | `number` | `20` | Canvas padding |
115
+ | `margin` | `number` | `4` | QR quiet zone (modules) |
116
+ | `errorCorrectionLevel` | `'L'\|'M'\|'Q'\|'H'` | `'M'` | Error correction |
117
+
118
+ ### Styling Options
119
+
120
+ | Option | Type | Default | Description |
121
+ |--------|------|---------|-------------|
122
+ | `rounded` | `boolean` | `false` | Use rounded corners |
123
+ | `moduleRadius` | `number` | `0.5` | Module corner radius (0-0.5) |
124
+ | `cornerRadius` | `number` | `30` | Background corner radius |
125
+ | `gradient` | `boolean` | `false` | Enable gradient |
126
+ | `gradientColors` | `string` | - | Comma-separated colors |
127
+ | `gradientAngle` | `number` | `45` | Gradient angle |
128
+
129
+ ### Logo Options
130
+
131
+ | Option | Type | Default | Description |
132
+ |--------|------|---------|-------------|
133
+ | `logo` | `string\|HTMLImageElement` | - | Logo path/URL or image element |
134
+ | `logoSize` | `number` | - | Logo size override |
135
+ | `logoPadding` | `number` | `20` | Padding around logo |
136
+ | `logoShape` | `'circle'\|'square'` | `'circle'` | Logo background shape |
137
+ | `logoRadius` | `number` | `10` | Square logo corner radius |
138
+
139
+ ### Eye Customization
140
+
141
+ | Option | Type | Default | Description |
142
+ |--------|------|---------|-------------|
143
+ | `eyeColor` | `string` | - | Custom eye (finder) color |
144
+ | `eyeRadius` | `number` | - | Custom eye corner radius |
145
+
146
+ ## Examples
147
+
148
+ ### Basic QR Code
149
+
150
+ ```typescript
151
+ const qr = new QRGenerator({
152
+ url: 'https://example.com',
153
+ size: 400
154
+ });
155
+
156
+ await qr.appendTo(document.getElementById('qr-container'));
157
+ ```
158
+
159
+ ### Gradient QR Code
160
+
161
+ ```typescript
162
+ const qr = new QRGenerator({
163
+ url: 'https://example.com',
164
+ size: 400,
165
+ gradient: true,
166
+ gradientColors: '#667eea, #764ba2, #f093fb',
167
+ gradientAngle: 135,
168
+ rounded: true
169
+ });
170
+
171
+ await qr.download('gradient-qr.png');
172
+ ```
173
+
174
+ ### QR Code with Logo
175
+
176
+ ```typescript
177
+ const qr = new QRGenerator({
178
+ url: 'https://example.com',
179
+ size: 400,
180
+ foregroundColor: '#1a73e8',
181
+ logo: 'https://example.com/logo.png',
182
+ logoShape: 'circle',
183
+ rounded: true
184
+ });
185
+
186
+ const blob = await qr.generateToBlob();
187
+ ```
188
+
189
+ ### Using HTMLImageElement
190
+
191
+ ```typescript
192
+ const img = new Image();
193
+ img.src = 'logo.png';
194
+ await img.decode();
195
+
196
+ const qr = new QRGenerator({
197
+ url: 'https://example.com',
198
+ size: 400,
199
+ logo: img
200
+ });
201
+
202
+ await qr.appendTo(document.body);
203
+ ```
204
+
205
+ ### vCard Contact QR
206
+
207
+ ```typescript
208
+ import { QRGenerator, formatVCard } from '@qr-styled/browser';
209
+
210
+ const qr = new QRGenerator({
211
+ type: 'vcard',
212
+ data: {
213
+ firstName: 'John',
214
+ lastName: 'Doe',
215
+ organization: 'Company Inc.',
216
+ phone: '+1234567890',
217
+ email: 'john@example.com',
218
+ url: 'https://johndoe.com'
219
+ },
220
+ size: 400,
221
+ gradient: true,
222
+ gradientColors: '#667eea, #764ba2'
223
+ });
224
+
225
+ await qr.download('contact.png');
226
+ ```
227
+
228
+ ### WiFi QR Code
229
+
230
+ ```typescript
231
+ const qr = new QRGenerator({
232
+ type: 'wifi',
233
+ data: {
234
+ ssid: 'MyNetwork',
235
+ password: 'mypassword',
236
+ encryption: 'WPA'
237
+ },
238
+ size: 400,
239
+ foregroundColor: '#2196f3'
240
+ });
241
+
242
+ await qr.appendTo(document.body);
243
+ ```
244
+
245
+ ### SVG Export
246
+
247
+ ```typescript
248
+ const qr = new QRGenerator({
249
+ url: 'https://example.com',
250
+ size: 400,
251
+ foregroundColor: '#ff5722'
252
+ });
253
+
254
+ const svg = await qr.generateToSVG();
255
+ console.log(svg); // SVG string
256
+
257
+ // Or download directly
258
+ await qr.downloadSVG('qrcode.svg');
259
+ ```
260
+
261
+ ### Custom Eyes
262
+
263
+ ```typescript
264
+ const qr = new QRGenerator({
265
+ url: 'https://example.com',
266
+ size: 400,
267
+ foregroundColor: '#000000',
268
+ eyeColor: '#ff0000',
269
+ eyeRadius: 0.5,
270
+ rounded: true
271
+ });
272
+
273
+ await qr.download();
274
+ ```
275
+
276
+ ## Specialized QR Types
277
+
278
+ ### Email
279
+
280
+ ```typescript
281
+ const qr = new QRGenerator({
282
+ type: 'email',
283
+ data: {
284
+ email: 'hello@example.com',
285
+ subject: 'Hello',
286
+ body: 'Message body'
287
+ }
288
+ });
289
+ ```
290
+
291
+ ### SMS
292
+
293
+ ```typescript
294
+ const qr = new QRGenerator({
295
+ type: 'sms',
296
+ data: {
297
+ phone: '+1234567890',
298
+ message: 'Hello from QR'
299
+ }
300
+ });
301
+ ```
302
+
303
+ ### Geolocation
304
+
305
+ ```typescript
306
+ const qr = new QRGenerator({
307
+ type: 'geo',
308
+ data: {
309
+ latitude: 40.7128,
310
+ longitude: -74.0060
311
+ }
312
+ });
313
+ ```
314
+
315
+ ## Browser Compatibility
316
+
317
+ - Chrome/Edge 90+
318
+ - Firefox 88+
319
+ - Safari 14+
320
+ - Opera 76+
321
+
322
+ Requires support for:
323
+ - HTML5 Canvas API
324
+ - ES2020+ features
325
+ - Promises/async-await
326
+
327
+ ## Related Packages
328
+
329
+ - [@qr-styled/node](../node) - Node.js version with PNG/JPEG file export
330
+
331
+ ## License
332
+
333
+ MIT © Luis Manuel Yerena Sosa
334
+
335
+ ## Contributing
336
+
337
+ Contributions are welcome! Please open an issue or submit a pull request.
338
+
339
+ ## Repository
340
+
341
+ [https://github.com/Luisma92/qr-styled](https://github.com/Luisma92/qr-styled)
@@ -0,0 +1,3 @@
1
+ export { QRGenerator, generateQR, generateQRToElement, generateQRAndDownload } from './lib/QRGenerator.js';
2
+ export type { QROptions, QRDataType, VCardData, WiFiData, EmailData, SMSData, GeoData } from './lib/utils/types.js';
3
+ export { formatVCard, formatWiFi, formatEmail, formatSMS, formatGeo } from './lib/utils/formatters.js';
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { QRGenerator, generateQR, generateQRToElement, generateQRAndDownload } from './lib/QRGenerator.js';
2
+ export { formatVCard, formatWiFi, formatEmail, formatSMS, formatGeo } from './lib/utils/formatters.js';
@@ -0,0 +1,59 @@
1
+ import { QROptions } from './utils/types.js';
2
+ /**
3
+ * QR Code Generator with advanced styling options for browsers
4
+ */
5
+ export declare class QRGenerator {
6
+ private options;
7
+ /**
8
+ * Creates a new QR generator instance
9
+ */
10
+ constructor(options: QROptions);
11
+ /**
12
+ * Generates QR code content from options
13
+ */
14
+ private getQRContent;
15
+ /**
16
+ * Generates QR code and returns the canvas
17
+ */
18
+ generate(): Promise<HTMLCanvasElement>;
19
+ /**
20
+ * Generates QR code and returns data URL
21
+ */
22
+ generateToDataURL(format?: 'png' | 'jpeg'): Promise<string>;
23
+ /**
24
+ * Generates QR code and returns Blob
25
+ */
26
+ generateToBlob(format?: 'png' | 'jpeg'): Promise<Blob>;
27
+ /**
28
+ * Generates QR code and downloads it as an image file
29
+ */
30
+ download(filename?: string): Promise<void>;
31
+ /**
32
+ * Generates QR code as SVG string
33
+ */
34
+ generateToSVG(): Promise<string>;
35
+ /**
36
+ * Generates QR code as SVG and downloads it
37
+ */
38
+ downloadSVG(filename?: string): Promise<void>;
39
+ /**
40
+ * Appends the generated QR code canvas to a DOM element
41
+ */
42
+ appendTo(element: HTMLElement): Promise<HTMLCanvasElement>;
43
+ /**
44
+ * Updates generator options
45
+ */
46
+ updateOptions(options: Partial<QROptions>): void;
47
+ }
48
+ /**
49
+ * Helper function to quickly generate a QR code
50
+ */
51
+ export declare function generateQR(options: QROptions): Promise<HTMLCanvasElement>;
52
+ /**
53
+ * Helper function to quickly generate and append QR code to DOM
54
+ */
55
+ export declare function generateQRToElement(options: QROptions, element: HTMLElement): Promise<HTMLCanvasElement>;
56
+ /**
57
+ * Helper function to quickly generate and download QR code
58
+ */
59
+ export declare function generateQRAndDownload(options: QROptions, filename?: string): Promise<void>;
@@ -0,0 +1,184 @@
1
+ import QRCode from 'qrcode';
2
+ import { BackgroundRenderer } from './renderers/BackgroundRenderer.js';
3
+ import { GradientRenderer } from './renderers/GradientRenderer.js';
4
+ import { ModuleRenderer } from './renderers/ModuleRenderer.js';
5
+ import { LogoRenderer } from './renderers/LogoRenderer.js';
6
+ import { SVGRenderer } from './renderers/SVGRenderer.js';
7
+ import { DEFAULT_OPTIONS } from './utils/types.js';
8
+ import { validateOptions, normalizeOptions } from './utils/validators.js';
9
+ import { formatQRData } from './utils/formatters.js';
10
+ /**
11
+ * QR Code Generator with advanced styling options for browsers
12
+ */
13
+ export class QRGenerator {
14
+ /**
15
+ * Creates a new QR generator instance
16
+ */
17
+ constructor(options) {
18
+ this.options = normalizeOptions(options, DEFAULT_OPTIONS);
19
+ // Support deprecated 'color' field with backward compatibility
20
+ if (options.color && !options.foregroundColor) {
21
+ this.options.foregroundColor = options.color;
22
+ }
23
+ validateOptions(this.options);
24
+ }
25
+ /**
26
+ * Generates QR code content from options
27
+ */
28
+ getQRContent() {
29
+ const { type, url, data } = this.options;
30
+ // Use formatter to handle different data types
31
+ return formatQRData(type, url, data);
32
+ }
33
+ /**
34
+ * Generates QR code and returns the canvas
35
+ */
36
+ async generate() {
37
+ const { errorCorrectionLevel, size, padding, foregroundColor } = this.options;
38
+ const qrSize = size - padding * 2;
39
+ // Get formatted content based on type
40
+ const content = this.getQRContent();
41
+ // Generate QR data
42
+ const qrData = await QRCode.create(content, {
43
+ errorCorrectionLevel
44
+ });
45
+ const modules = qrData.modules;
46
+ const moduleCount = modules.size;
47
+ const moduleSize = qrSize / moduleCount;
48
+ // Create canvas
49
+ const canvas = document.createElement('canvas');
50
+ canvas.width = size;
51
+ canvas.height = size;
52
+ const ctx = canvas.getContext('2d');
53
+ if (!ctx) {
54
+ throw new Error('Failed to get 2D context from canvas. Canvas API may not be supported in this environment.');
55
+ }
56
+ // Render background
57
+ const backgroundRenderer = new BackgroundRenderer(ctx, this.options);
58
+ backgroundRenderer.render();
59
+ backgroundRenderer.applyClipping();
60
+ // Create fill style (gradient or solid)
61
+ const gradientRenderer = new GradientRenderer(ctx, this.options);
62
+ const fillStyle = gradientRenderer.getFillStyle();
63
+ // Render QR modules with eye customization support
64
+ const moduleRenderer = new ModuleRenderer(ctx, modules, {
65
+ ...this.options,
66
+ color: foregroundColor, // Use new foregroundColor
67
+ moduleCount,
68
+ moduleSize
69
+ });
70
+ moduleRenderer.render(fillStyle);
71
+ backgroundRenderer.restoreClipping();
72
+ // Render logo if provided
73
+ if (this.options.logo) {
74
+ const logoRenderer = new LogoRenderer(ctx, this.options);
75
+ await logoRenderer.render(this.options.logo);
76
+ }
77
+ return canvas;
78
+ }
79
+ /**
80
+ * Generates QR code and returns data URL
81
+ */
82
+ async generateToDataURL(format = 'png') {
83
+ const canvas = await this.generate();
84
+ if (format === 'jpeg') {
85
+ return canvas.toDataURL('image/jpeg');
86
+ }
87
+ return canvas.toDataURL('image/png');
88
+ }
89
+ /**
90
+ * Generates QR code and returns Blob
91
+ */
92
+ async generateToBlob(format = 'png') {
93
+ const canvas = await this.generate();
94
+ return new Promise((resolve, reject) => {
95
+ canvas.toBlob(blob => {
96
+ if (blob) {
97
+ resolve(blob);
98
+ }
99
+ else {
100
+ reject(new Error('Failed to generate blob'));
101
+ }
102
+ }, format === 'jpeg' ? 'image/jpeg' : 'image/png');
103
+ });
104
+ }
105
+ /**
106
+ * Generates QR code and downloads it as an image file
107
+ */
108
+ async download(filename = 'qrcode.png') {
109
+ const format = filename.endsWith('.jpeg') || filename.endsWith('.jpg') ? 'jpeg' : 'png';
110
+ const dataURL = await this.generateToDataURL(format);
111
+ const link = document.createElement('a');
112
+ link.href = dataURL;
113
+ link.download = filename;
114
+ link.click();
115
+ }
116
+ /**
117
+ * Generates QR code as SVG string
118
+ */
119
+ async generateToSVG() {
120
+ const { errorCorrectionLevel, size } = this.options;
121
+ // Get formatted content based on type
122
+ const content = this.getQRContent();
123
+ // Generate QR data
124
+ const qrData = await QRCode.create(content, {
125
+ errorCorrectionLevel
126
+ });
127
+ // Use SVG renderer
128
+ const svgRenderer = new SVGRenderer(qrData, this.options, size);
129
+ return svgRenderer.generate();
130
+ }
131
+ /**
132
+ * Generates QR code as SVG and downloads it
133
+ */
134
+ async downloadSVG(filename = 'qrcode.svg') {
135
+ const svg = await this.generateToSVG();
136
+ const blob = new Blob([svg], { type: 'image/svg+xml' });
137
+ const url = URL.createObjectURL(blob);
138
+ const link = document.createElement('a');
139
+ link.href = url;
140
+ link.download = filename;
141
+ link.click();
142
+ URL.revokeObjectURL(url);
143
+ }
144
+ /**
145
+ * Appends the generated QR code canvas to a DOM element
146
+ */
147
+ async appendTo(element) {
148
+ const canvas = await this.generate();
149
+ element.appendChild(canvas);
150
+ return canvas;
151
+ }
152
+ /**
153
+ * Updates generator options
154
+ */
155
+ updateOptions(options) {
156
+ this.options = normalizeOptions({ ...this.options, ...options }, DEFAULT_OPTIONS);
157
+ // Support deprecated 'color' field
158
+ if (options.color && !options.foregroundColor) {
159
+ this.options.foregroundColor = options.color;
160
+ }
161
+ validateOptions(this.options);
162
+ }
163
+ }
164
+ /**
165
+ * Helper function to quickly generate a QR code
166
+ */
167
+ export async function generateQR(options) {
168
+ const generator = new QRGenerator(options);
169
+ return generator.generate();
170
+ }
171
+ /**
172
+ * Helper function to quickly generate and append QR code to DOM
173
+ */
174
+ export async function generateQRToElement(options, element) {
175
+ const generator = new QRGenerator(options);
176
+ return generator.appendTo(element);
177
+ }
178
+ /**
179
+ * Helper function to quickly generate and download QR code
180
+ */
181
+ export async function generateQRAndDownload(options, filename) {
182
+ const generator = new QRGenerator(options);
183
+ return generator.download(filename);
184
+ }
@@ -0,0 +1,21 @@
1
+ import { QROptions } from '../utils/types.js';
2
+ /**
3
+ * Handles background rendering for QR codes
4
+ */
5
+ export declare class BackgroundRenderer {
6
+ private ctx;
7
+ private options;
8
+ constructor(ctx: CanvasRenderingContext2D, options: Required<QROptions>);
9
+ /**
10
+ * Renders background with rounded corners
11
+ */
12
+ render(): void;
13
+ /**
14
+ * Applies clipping path for rounded corners
15
+ */
16
+ applyClipping(): void;
17
+ /**
18
+ * Restores canvas context after clipping
19
+ */
20
+ restoreClipping(): void;
21
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Handles background rendering for QR codes
3
+ */
4
+ export class BackgroundRenderer {
5
+ constructor(ctx, options) {
6
+ this.ctx = ctx;
7
+ this.options = options;
8
+ }
9
+ /**
10
+ * Renders background with rounded corners
11
+ */
12
+ render() {
13
+ const { size, cornerRadius, backgroundColor } = this.options;
14
+ const ctx = this.ctx;
15
+ ctx.fillStyle = backgroundColor;
16
+ ctx.beginPath();
17
+ ctx.moveTo(cornerRadius, 0);
18
+ ctx.arcTo(size, 0, size, size, cornerRadius);
19
+ ctx.arcTo(size, size, 0, size, cornerRadius);
20
+ ctx.arcTo(0, size, 0, 0, cornerRadius);
21
+ ctx.arcTo(0, 0, size, 0, cornerRadius);
22
+ ctx.closePath();
23
+ ctx.fill();
24
+ }
25
+ /**
26
+ * Applies clipping path for rounded corners
27
+ */
28
+ applyClipping() {
29
+ const { size, cornerRadius } = this.options;
30
+ const ctx = this.ctx;
31
+ ctx.save();
32
+ ctx.beginPath();
33
+ ctx.moveTo(cornerRadius, 0);
34
+ ctx.arcTo(size, 0, size, size, cornerRadius);
35
+ ctx.arcTo(size, size, 0, size, cornerRadius);
36
+ ctx.arcTo(0, size, 0, 0, cornerRadius);
37
+ ctx.arcTo(0, 0, size, 0, cornerRadius);
38
+ ctx.closePath();
39
+ ctx.clip();
40
+ }
41
+ /**
42
+ * Restores canvas context after clipping
43
+ */
44
+ restoreClipping() {
45
+ this.ctx.restore();
46
+ }
47
+ }
@@ -0,0 +1,17 @@
1
+ import { QROptions } from '../utils/types.js';
2
+ /**
3
+ * Handles gradient creation for QR codes
4
+ */
5
+ export declare class GradientRenderer {
6
+ private ctx;
7
+ private options;
8
+ constructor(ctx: CanvasRenderingContext2D, options: Required<QROptions>);
9
+ /**
10
+ * Creates a gradient fill style
11
+ */
12
+ createGradient(): CanvasGradient;
13
+ /**
14
+ * Gets the appropriate fill style (gradient or solid color)
15
+ */
16
+ getFillStyle(): string | CanvasGradient;
17
+ }