favicon-animate 0.1.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.
@@ -0,0 +1,61 @@
1
+ import { AnimatorOptions, BadgeConfig, FaviconConfig, FaviconData } from './types';
2
+ /**
3
+ * Main FaviconAnimator class
4
+ */
5
+ export declare class FaviconAnimator {
6
+ private faviconLink;
7
+ private currentFavicon;
8
+ private currentBadge;
9
+ private isAnimating;
10
+ private pauseOnHidden;
11
+ private isVisible;
12
+ private unsubscribeVisibility;
13
+ private faviconSize;
14
+ private updateInterval;
15
+ constructor(options?: AnimatorOptions);
16
+ /**
17
+ * Set favicon
18
+ */
19
+ setFavicon(config: FaviconConfig | string): Promise<void>;
20
+ /**
21
+ * Set badge
22
+ */
23
+ setBadge(config: BadgeConfig): void;
24
+ /**
25
+ * Update badge
26
+ */
27
+ updateBadge(number: number | string): void;
28
+ /**
29
+ * Remove badge
30
+ */
31
+ removeBadge(): void;
32
+ /**
33
+ * Update favicon display (with badge if configured)
34
+ */
35
+ private updateFaviconDisplay;
36
+ /**
37
+ * Pause animation
38
+ */
39
+ pause(): void;
40
+ /**
41
+ * Resume animation
42
+ */
43
+ resume(): void;
44
+ /**
45
+ * Get current favicon data
46
+ */
47
+ getFavicon(): FaviconData | null;
48
+ /**
49
+ * Get current badge config
50
+ */
51
+ getBadge(): BadgeConfig | null;
52
+ /**
53
+ * Check if currently animating
54
+ */
55
+ getIsAnimating(): boolean;
56
+ /**
57
+ * Cleanup
58
+ */
59
+ destroy(): void;
60
+ }
61
+ //# sourceMappingURL=animator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animator.d.ts","sourceRoot":"","sources":["../src/animator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAYnF;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,qBAAqB,CAA6B;IAC1D,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,cAAc,CAAe;gBAEzB,OAAO,GAAE,eAAoB;IAoCzC;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B/D;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IASnC;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAU1C;;OAEG;IACH,WAAW,IAAI,IAAI;IAKnB;;OAEG;YACW,oBAAoB;IAiClC;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,MAAM,IAAI,IAAI;IAMd;;OAEG;IACH,UAAU,IAAI,WAAW,GAAG,IAAI;IAIhC;;OAEG;IACH,QAAQ,IAAI,WAAW,GAAG,IAAI;IAI9B;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=animator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animator.test.d.ts","sourceRoot":"","sources":["../src/animator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import { BadgeConfig, BadgePosition } from './types';
2
+ /**
3
+ * Badge rendering utilities
4
+ */
5
+ export declare class BadgeRenderer {
6
+ /**
7
+ * Calculate badge position coordinates
8
+ */
9
+ static calculatePosition(position: BadgePosition, faviconSize: number, badgeSize: number, offset?: number): {
10
+ x: number;
11
+ y: number;
12
+ };
13
+ /**
14
+ * Draw badge on canvas
15
+ */
16
+ static drawBadge(ctx: CanvasRenderingContext2D, config: BadgeConfig, faviconSize: number): void;
17
+ /**
18
+ * Validate badge configuration
19
+ */
20
+ static validateConfig(config: Partial<BadgeConfig>): BadgeConfig;
21
+ }
22
+ //# sourceMappingURL=badge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../src/badge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAErD;;GAEG;AAEH,qBAAa,aAAa;IACxB;;OAEG;IACH,MAAM,CAAC,iBAAiB,CACtB,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,MAAU,GACjB;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAmB3B;;OAEG;IACH,MAAM,CAAC,SAAS,CACd,GAAG,EAAE,wBAAwB,EAC7B,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,MAAM,GAClB,IAAI;IAiCP;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW;CA4CjE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=badge.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.test.d.ts","sourceRoot":"","sources":["../src/badge.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * favicon-animate - Lightweight favicon animation library
3
+ * @version 0.1.0
4
+ * @license MIT
5
+ */
6
+ export { FaviconAnimator } from './animator';
7
+ export { BadgeRenderer } from './badge';
8
+ export { getVisibilityManager, VisibilityManager } from './visibility';
9
+ export type { BadgePosition, BadgeConfig, FaviconConfig, AnimatorOptions, VisibilityState, FaviconData } from './types';
10
+ export { getFaviconLink, createCanvas, loadImage, detectImageFormat, supportsPageVisibility, debounce, throttle, canvasToDataUrl, isBrowser } from './utils';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGvE,YAAY,EACV,aAAa,EACb,WAAW,EACX,aAAa,EACb,eAAe,EACf,eAAe,EACf,WAAW,EACZ,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,cAAc,EACd,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,sBAAsB,EACtB,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,SAAS,EACV,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,436 @@
1
+ /**
2
+ * Badge rendering utilities
3
+ */
4
+ class BadgeRenderer {
5
+ /**
6
+ * Calculate badge position coordinates
7
+ */
8
+ static calculatePosition(position, faviconSize, badgeSize, offset = 2) {
9
+ const badgeRadius = badgeSize / 2;
10
+ switch (position) {
11
+ case 'top-left':
12
+ return { x: offset + badgeRadius, y: offset + badgeRadius };
13
+ case 'top-right':
14
+ return { x: faviconSize - offset - badgeRadius, y: offset + badgeRadius };
15
+ case 'bottom-left':
16
+ return { x: offset + badgeRadius, y: faviconSize - offset - badgeRadius };
17
+ case 'bottom-right':
18
+ return { x: faviconSize - offset - badgeRadius, y: faviconSize - offset - badgeRadius };
19
+ case 'center':
20
+ return { x: faviconSize / 2, y: faviconSize / 2 };
21
+ default:
22
+ return { x: faviconSize - offset - badgeRadius, y: offset + badgeRadius };
23
+ }
24
+ }
25
+ /**
26
+ * Draw badge on canvas
27
+ */
28
+ static drawBadge(ctx, config, faviconSize) {
29
+ const { number, position, backgroundColor = '#FF0000', textColor = '#FFFFFF', size = 16, fontSize = 12, borderRadius = '50%', offset = 2, fontWeight = 'bold', fontFamily = 'Arial, sans-serif' } = config;
30
+ const { x, y } = this.calculatePosition(position, faviconSize, size, offset);
31
+ // Draw badge background circle
32
+ ctx.fillStyle = backgroundColor;
33
+ ctx.beginPath();
34
+ ctx.arc(x, y, size / 2, 0, Math.PI * 2);
35
+ ctx.fill();
36
+ // Draw badge text
37
+ ctx.fillStyle = textColor;
38
+ ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
39
+ ctx.textAlign = 'center';
40
+ ctx.textBaseline = 'middle';
41
+ // Ensure number fits in badge
42
+ const numberStr = String(number).substring(0, 3);
43
+ ctx.fillText(numberStr, x, y);
44
+ }
45
+ /**
46
+ * Validate badge configuration
47
+ */
48
+ static validateConfig(config) {
49
+ const { number = 1, position = 'top-right', backgroundColor = '#FF0000', textColor = '#FFFFFF', size = 16, fontSize = 12, borderRadius = '50%', offset = 2, fontWeight = 'bold', fontFamily = 'Arial, sans-serif' } = config;
50
+ // Validate position
51
+ const validPositions = [
52
+ 'top-left',
53
+ 'top-right',
54
+ 'bottom-left',
55
+ 'bottom-right',
56
+ 'center'
57
+ ];
58
+ if (!validPositions.includes(position)) {
59
+ throw new Error(`Invalid badge position: ${position}`);
60
+ }
61
+ // Validate number
62
+ if (typeof number !== 'number' && typeof number !== 'string') {
63
+ throw new Error('Badge number must be a number or string');
64
+ }
65
+ return {
66
+ number,
67
+ position: position,
68
+ backgroundColor,
69
+ textColor,
70
+ size: Math.max(8, size),
71
+ fontSize: Math.max(6, fontSize),
72
+ borderRadius,
73
+ offset: Math.max(0, offset),
74
+ fontWeight,
75
+ fontFamily
76
+ };
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Page Visibility API wrapper for managing favicon animations
82
+ * when the tab is not in focus
83
+ */
84
+ class VisibilityManager {
85
+ constructor() {
86
+ this.isVisible = true;
87
+ this.callbacks = new Set();
88
+ this.boundHandleVisibilityChange = this.handleVisibilityChange.bind(this);
89
+ this.init();
90
+ }
91
+ init() {
92
+ // Check initial visibility state
93
+ this.isVisible = !document.hidden;
94
+ // Listen for visibility changes
95
+ document.addEventListener('visibilitychange', this.boundHandleVisibilityChange);
96
+ }
97
+ handleVisibilityChange() {
98
+ const wasVisible = this.isVisible;
99
+ this.isVisible = !document.hidden;
100
+ // Only notify if state actually changed
101
+ if (wasVisible !== this.isVisible) {
102
+ this.notifyCallbacks();
103
+ }
104
+ }
105
+ notifyCallbacks() {
106
+ this.callbacks.forEach(callback => {
107
+ try {
108
+ callback(this.isVisible);
109
+ }
110
+ catch (error) {
111
+ console.error('Error in visibility callback:', error);
112
+ }
113
+ });
114
+ }
115
+ /**
116
+ * Subscribe to visibility changes
117
+ */
118
+ onChange(callback) {
119
+ this.callbacks.add(callback);
120
+ // Return unsubscribe function
121
+ return () => {
122
+ this.callbacks.delete(callback);
123
+ };
124
+ }
125
+ /**
126
+ * Get current visibility state
127
+ */
128
+ getIsVisible() {
129
+ return this.isVisible;
130
+ }
131
+ /**
132
+ * Cleanup
133
+ */
134
+ destroy() {
135
+ document.removeEventListener('visibilitychange', this.boundHandleVisibilityChange);
136
+ this.callbacks.clear();
137
+ }
138
+ }
139
+ // Singleton instance
140
+ let visibilityManager = null;
141
+ function getVisibilityManager() {
142
+ if (!visibilityManager) {
143
+ visibilityManager = new VisibilityManager();
144
+ }
145
+ return visibilityManager;
146
+ }
147
+
148
+ /**
149
+ * Utility functions
150
+ */
151
+ /**
152
+ * Get or create favicon link element
153
+ */
154
+ function getFaviconLink() {
155
+ let link = document.querySelector('link[rel="icon"]');
156
+ if (!link) {
157
+ link = document.createElement('link');
158
+ link.rel = 'icon';
159
+ link.type = 'image/png';
160
+ document.head.appendChild(link);
161
+ }
162
+ return link;
163
+ }
164
+ /**
165
+ * Create canvas element
166
+ */
167
+ function createCanvas(size) {
168
+ const canvas = document.createElement('canvas');
169
+ canvas.width = size;
170
+ canvas.height = size;
171
+ return canvas;
172
+ }
173
+ /**
174
+ * Load image from URL
175
+ */
176
+ function loadImage(url) {
177
+ return new Promise((resolve, reject) => {
178
+ const img = new Image();
179
+ img.onload = () => resolve(img);
180
+ img.onerror = () => reject(new Error(`Failed to load image: ${url}`));
181
+ img.src = url;
182
+ });
183
+ }
184
+ /**
185
+ * Detect image format from URL or data URL
186
+ */
187
+ function detectImageFormat(url) {
188
+ if (url.startsWith('data:')) {
189
+ const mimeType = url.split(';')[0].split(':')[1];
190
+ if (mimeType.includes('gif'))
191
+ return 'gif';
192
+ if (mimeType.includes('webp'))
193
+ return 'webp';
194
+ if (mimeType.includes('svg'))
195
+ return 'svg';
196
+ if (mimeType.includes('png'))
197
+ return 'png';
198
+ if (mimeType.includes('icon'))
199
+ return 'ico';
200
+ }
201
+ else {
202
+ const ext = url.split('.').pop()?.toLowerCase();
203
+ if (ext === 'gif')
204
+ return 'gif';
205
+ if (ext === 'webp')
206
+ return 'webp';
207
+ if (ext === 'svg')
208
+ return 'svg';
209
+ if (ext === 'ico')
210
+ return 'ico';
211
+ if (ext === 'png')
212
+ return 'png';
213
+ }
214
+ return 'unknown';
215
+ }
216
+ /**
217
+ * Check if browser supports Page Visibility API
218
+ */
219
+ function supportsPageVisibility() {
220
+ return typeof document.hidden !== 'undefined';
221
+ }
222
+ /**
223
+ * Debounce function
224
+ */
225
+ function debounce(func, wait) {
226
+ let timeout;
227
+ return function executedFunction(...args) {
228
+ const later = () => {
229
+ clearTimeout(timeout);
230
+ func(...args);
231
+ };
232
+ clearTimeout(timeout);
233
+ timeout = setTimeout(later, wait);
234
+ };
235
+ }
236
+ /**
237
+ * Throttle function
238
+ */
239
+ function throttle(func, limit) {
240
+ let inThrottle;
241
+ return function executedFunction(...args) {
242
+ if (!inThrottle) {
243
+ func(...args);
244
+ inThrottle = true;
245
+ setTimeout(() => (inThrottle = false), limit);
246
+ }
247
+ };
248
+ }
249
+ /**
250
+ * Convert canvas to data URL
251
+ */
252
+ function canvasToDataUrl(canvas) {
253
+ return canvas.toDataURL('image/png');
254
+ }
255
+ /**
256
+ * Check if running in browser environment
257
+ */
258
+ function isBrowser() {
259
+ return typeof window !== 'undefined' && typeof document !== 'undefined';
260
+ }
261
+
262
+ /**
263
+ * Main FaviconAnimator class
264
+ */
265
+ class FaviconAnimator {
266
+ constructor(options = {}) {
267
+ this.currentFavicon = null;
268
+ this.currentBadge = null;
269
+ this.isAnimating = false;
270
+ this.pauseOnHidden = true;
271
+ this.isVisible = true;
272
+ this.unsubscribeVisibility = null;
273
+ this.faviconSize = 32;
274
+ this.updateInterval = 100;
275
+ if (!isBrowser()) {
276
+ throw new Error('FaviconAnimator can only be used in browser environment');
277
+ }
278
+ this.faviconLink = getFaviconLink();
279
+ this.pauseOnHidden = options.pauseOnHidden !== false;
280
+ this.updateInterval = options.updateInterval || 100;
281
+ // Setup visibility manager
282
+ if (this.pauseOnHidden) {
283
+ const visibilityManager = getVisibilityManager();
284
+ this.unsubscribeVisibility = visibilityManager.onChange(isVisible => {
285
+ this.isVisible = isVisible;
286
+ if (isVisible) {
287
+ this.resume();
288
+ }
289
+ else {
290
+ this.pause();
291
+ }
292
+ });
293
+ }
294
+ // Set initial favicon if provided
295
+ if (options.favicon) {
296
+ const faviconConfig = typeof options.favicon === 'string'
297
+ ? { url: options.favicon }
298
+ : options.favicon;
299
+ this.setFavicon(faviconConfig);
300
+ }
301
+ // Set initial badge if provided
302
+ if (options.badge) {
303
+ this.setBadge(options.badge);
304
+ }
305
+ }
306
+ /**
307
+ * Set favicon
308
+ */
309
+ async setFavicon(config) {
310
+ const faviconConfig = typeof config === 'string'
311
+ ? { url: config }
312
+ : config;
313
+ const { url, size = 32 } = faviconConfig;
314
+ this.faviconSize = size;
315
+ try {
316
+ // Detect format
317
+ const format = detectImageFormat(url);
318
+ // Create favicon data
319
+ this.currentFavicon = {
320
+ url,
321
+ size,
322
+ isAnimated: format === 'gif' || format === 'webp',
323
+ format
324
+ };
325
+ // Update favicon link
326
+ await this.updateFaviconDisplay();
327
+ }
328
+ catch (error) {
329
+ console.error('Error setting favicon:', error);
330
+ }
331
+ }
332
+ /**
333
+ * Set badge
334
+ */
335
+ setBadge(config) {
336
+ try {
337
+ this.currentBadge = BadgeRenderer.validateConfig(config);
338
+ this.updateFaviconDisplay();
339
+ }
340
+ catch (error) {
341
+ console.error('Error setting badge:', error);
342
+ }
343
+ }
344
+ /**
345
+ * Update badge
346
+ */
347
+ updateBadge(number) {
348
+ if (!this.currentBadge) {
349
+ console.warn('No badge configured. Call setBadge first.');
350
+ return;
351
+ }
352
+ this.currentBadge.number = number;
353
+ this.updateFaviconDisplay();
354
+ }
355
+ /**
356
+ * Remove badge
357
+ */
358
+ removeBadge() {
359
+ this.currentBadge = null;
360
+ this.updateFaviconDisplay();
361
+ }
362
+ /**
363
+ * Update favicon display (with badge if configured)
364
+ */
365
+ async updateFaviconDisplay() {
366
+ if (!this.currentFavicon)
367
+ return;
368
+ try {
369
+ let displayUrl = this.currentFavicon.url;
370
+ // If badge is configured, render it on canvas
371
+ if (this.currentBadge) {
372
+ const canvas = createCanvas(this.faviconSize);
373
+ const ctx = canvas.getContext('2d');
374
+ if (!ctx) {
375
+ throw new Error('Failed to get canvas context');
376
+ }
377
+ // Load and draw favicon image
378
+ const img = await loadImage(this.currentFavicon.url);
379
+ ctx.drawImage(img, 0, 0, this.faviconSize, this.faviconSize);
380
+ // Draw badge on top
381
+ BadgeRenderer.drawBadge(ctx, this.currentBadge, this.faviconSize);
382
+ // Convert to data URL
383
+ displayUrl = canvasToDataUrl(canvas);
384
+ }
385
+ // Update favicon link
386
+ this.faviconLink.href = displayUrl;
387
+ }
388
+ catch (error) {
389
+ console.error('Error updating favicon display:', error);
390
+ }
391
+ }
392
+ /**
393
+ * Pause animation
394
+ */
395
+ pause() {
396
+ this.isAnimating = false;
397
+ }
398
+ /**
399
+ * Resume animation
400
+ */
401
+ resume() {
402
+ if (this.isVisible) {
403
+ this.isAnimating = true;
404
+ }
405
+ }
406
+ /**
407
+ * Get current favicon data
408
+ */
409
+ getFavicon() {
410
+ return this.currentFavicon;
411
+ }
412
+ /**
413
+ * Get current badge config
414
+ */
415
+ getBadge() {
416
+ return this.currentBadge;
417
+ }
418
+ /**
419
+ * Check if currently animating
420
+ */
421
+ getIsAnimating() {
422
+ return this.isAnimating;
423
+ }
424
+ /**
425
+ * Cleanup
426
+ */
427
+ destroy() {
428
+ this.pause();
429
+ if (this.unsubscribeVisibility) {
430
+ this.unsubscribeVisibility();
431
+ }
432
+ }
433
+ }
434
+
435
+ export { BadgeRenderer, FaviconAnimator, VisibilityManager, canvasToDataUrl, createCanvas, debounce, detectImageFormat, getFaviconLink, getVisibilityManager, isBrowser, loadImage, supportsPageVisibility, throttle };
436
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/badge.ts","../src/visibility.ts","../src/utils.ts","../src/animator.ts"],"sourcesContent":[null,null,null,null],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Badge position options
3
+ */
4
+ export type BadgePosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'center';
5
+ /**
6
+ * Badge configuration
7
+ */
8
+ export interface BadgeConfig {
9
+ /** Number to display in the badge */
10
+ number: number | string;
11
+ /** Position of the badge */
12
+ position: BadgePosition;
13
+ /** Background color of the badge circle */
14
+ backgroundColor?: string;
15
+ /** Text color of the badge number */
16
+ textColor?: string;
17
+ /** Size of the badge circle in pixels */
18
+ size?: number;
19
+ /** Font size of the badge number */
20
+ fontSize?: number;
21
+ /** Border radius (usually '50%' for circle) */
22
+ borderRadius?: string;
23
+ /** Offset from the edge in pixels */
24
+ offset?: number;
25
+ /** Font weight */
26
+ fontWeight?: string | number;
27
+ /** Font family */
28
+ fontFamily?: string;
29
+ }
30
+ /**
31
+ * Favicon configuration
32
+ */
33
+ export interface FaviconConfig {
34
+ /** URL or data URL of the favicon */
35
+ url: string;
36
+ /** Size of the favicon in pixels (default: 32) */
37
+ size?: number;
38
+ /** Whether to use the favicon as-is or process it */
39
+ raw?: boolean;
40
+ }
41
+ /**
42
+ * Animator options
43
+ */
44
+ export interface AnimatorOptions {
45
+ /** Initial favicon URL or config */
46
+ favicon?: FaviconConfig | string;
47
+ /** Initial badge configuration */
48
+ badge?: BadgeConfig;
49
+ /** Whether to pause animation when tab is not visible */
50
+ pauseOnHidden?: boolean;
51
+ /** Update interval for badge changes (ms) */
52
+ updateInterval?: number;
53
+ /** Custom favicon link element selector */
54
+ linkSelector?: string;
55
+ }
56
+ /**
57
+ * Page visibility state
58
+ */
59
+ export interface VisibilityState {
60
+ isVisible: boolean;
61
+ wasVisible: boolean;
62
+ }
63
+ /**
64
+ * Favicon data for rendering
65
+ */
66
+ export interface FaviconData {
67
+ url: string;
68
+ size: number;
69
+ isAnimated: boolean;
70
+ format: 'gif' | 'webp' | 'png' | 'ico' | 'svg' | 'unknown';
71
+ }
72
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,GAAG,QAAQ,CAAC;AAEjG;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,4BAA4B;IAC5B,QAAQ,EAAE,aAAa,CAAC;IACxB,2CAA2C;IAC3C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,oCAAoC;IACpC,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;IACjC,kCAAkC;IAClC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,yDAAyD;IACzD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;CAC5D"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Utility functions
3
+ */
4
+ /**
5
+ * Get or create favicon link element
6
+ */
7
+ export declare function getFaviconLink(): HTMLLinkElement;
8
+ /**
9
+ * Create canvas element
10
+ */
11
+ export declare function createCanvas(size: number): HTMLCanvasElement;
12
+ /**
13
+ * Load image from URL
14
+ */
15
+ export declare function loadImage(url: string): Promise<HTMLImageElement>;
16
+ /**
17
+ * Detect image format from URL or data URL
18
+ */
19
+ export declare function detectImageFormat(url: string): 'gif' | 'webp' | 'png' | 'ico' | 'svg' | 'unknown';
20
+ /**
21
+ * Check if browser supports Page Visibility API
22
+ */
23
+ export declare function supportsPageVisibility(): boolean;
24
+ /**
25
+ * Debounce function
26
+ */
27
+ export declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void;
28
+ /**
29
+ * Throttle function
30
+ */
31
+ export declare function throttle<T extends (...args: any[]) => any>(func: T, limit: number): (...args: Parameters<T>) => void;
32
+ /**
33
+ * Convert canvas to data URL
34
+ */
35
+ export declare function canvasToDataUrl(canvas: HTMLCanvasElement): string;
36
+ /**
37
+ * Check if running in browser environment
38
+ */
39
+ export declare function isBrowser(): boolean;
40
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,cAAc,IAAI,eAAe,CAWhD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAK5D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAOhE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAiBjG;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,MAAM,GACX,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAYlC;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,MAAM,GACZ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAUlC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAEjE;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Page Visibility API wrapper for managing favicon animations
3
+ * when the tab is not in focus
4
+ */
5
+ export type VisibilityChangeCallback = (isVisible: boolean) => void;
6
+ export declare class VisibilityManager {
7
+ private isVisible;
8
+ private callbacks;
9
+ private boundHandleVisibilityChange;
10
+ constructor();
11
+ private init;
12
+ private handleVisibilityChange;
13
+ private notifyCallbacks;
14
+ /**
15
+ * Subscribe to visibility changes
16
+ */
17
+ onChange(callback: VisibilityChangeCallback): () => void;
18
+ /**
19
+ * Get current visibility state
20
+ */
21
+ getIsVisible(): boolean;
22
+ /**
23
+ * Cleanup
24
+ */
25
+ destroy(): void;
26
+ }
27
+ export declare function getVisibilityManager(): VisibilityManager;
28
+ //# sourceMappingURL=visibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visibility.d.ts","sourceRoot":"","sources":["../src/visibility.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,wBAAwB,GAAG,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;AAEpE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,SAAS,CAA4C;IAC7D,OAAO,CAAC,2BAA2B,CAAa;;IAOhD,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,sBAAsB;IAU9B,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,GAAG,MAAM,IAAI;IASxD;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,OAAO,IAAI,IAAI;CAIhB;AAKD,wBAAgB,oBAAoB,IAAI,iBAAiB,CAKxD"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "favicon-animate",
3
+ "version": "0.1.0",
4
+ "description": "Lightweight favicon animation library with badge support",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "rollup -c",
20
+ "dev": "rollup -c -w",
21
+ "test": "vitest",
22
+ "lint": "eslint src",
23
+ "format": "prettier --write src"
24
+ },
25
+ "keywords": [
26
+ "favicon",
27
+ "animate",
28
+ "dynamic",
29
+ "badge",
30
+ "notification"
31
+ ],
32
+ "author": "Daniel Belintani <daniel.belintani@hotmail.com>",
33
+ "license": "MIT",
34
+ "devDependencies": {
35
+ "@rollup/plugin-typescript": "^11.0.0",
36
+ "@types/node": "^20.0.0",
37
+ "rollup": "^4.0.0",
38
+ "typescript": "^5.3.0",
39
+ "vitest": "^1.0.0"
40
+ }
41
+ }