cursor-fx 1.1.1 → 1.1.3
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/README.md +105 -10
- package/dist/core/index.d.mts +3 -4
- package/dist/core/index.d.ts +3 -4
- package/dist/{engine-DtYS3_cn.d.mts → engine-D48zN1W8.d.mts} +1 -1
- package/dist/{engine-BiVjsHvN.d.ts → engine-OdnQ6Ya5.d.ts} +1 -1
- package/dist/{particle-CimoPApW.d.mts → imageLoader-VUu0PjNk.d.mts} +13 -1
- package/dist/{particle-CimoPApW.d.ts → imageLoader-VUu0PjNk.d.ts} +13 -1
- package/dist/react/index.d.mts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +3 -4
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +3 -4
- package/dist/react/index.mjs.map +1 -1
- package/dist/vanilla/index.d.mts +1 -2
- package/dist/vanilla/index.d.ts +1 -2
- package/package.json +3 -3
- package/dist/imageLoader-Bgr5GJIX.d.mts +0 -13
- package/dist/imageLoader-Bgr5GJIX.d.ts +0 -13
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Beautiful, customizable cursor particle effects for React and vanilla JavaScript
|
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
8
8
|
|
|
9
|
-
**[🎮 Live Demo](https://
|
|
9
|
+
**[🎮 Live Demo](https://www.antoprav.in/work/cursor-fx)** | **[📖 Documentation](#-api-reference)** | **[⭐ GitHub](https://github.com/antopravin-dev/cursor-fx)**
|
|
10
10
|
|
|
11
11
|
## ✨ Features
|
|
12
12
|
|
|
@@ -306,24 +306,119 @@ engine.destroy();
|
|
|
306
306
|
|
|
307
307
|
## 🖼️ Using Image Assets
|
|
308
308
|
|
|
309
|
-
|
|
309
|
+
The **Bubble** and **Snow** effects support PNG images for photorealistic quality. If images aren't loaded, they automatically fall back to canvas-drawn shapes.
|
|
310
|
+
|
|
311
|
+
### Setting Up Image Assets
|
|
312
|
+
|
|
313
|
+
**1. Copy the images to your public directory:**
|
|
314
|
+
|
|
315
|
+
The package includes high-quality PNG assets. Copy them from `node_modules/cursor-fx/dist/bubbles/` and `node_modules/cursor-fx/dist/snowflakes/` to your project's public directory:
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# Example structure
|
|
319
|
+
public/
|
|
320
|
+
bubbles/
|
|
321
|
+
soap_bubbles_1.png
|
|
322
|
+
soap_bubble_2.png
|
|
323
|
+
soap_bubble_3.png
|
|
324
|
+
snowflakes/
|
|
325
|
+
snow_flake_1.png
|
|
326
|
+
snow_flake_2.png
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**2. Preload images before using the effects:**
|
|
330
|
+
|
|
331
|
+
### React Example
|
|
332
|
+
|
|
333
|
+
```tsx
|
|
334
|
+
import { useEffect } from 'react';
|
|
335
|
+
import { CursorFX, ImageLoader } from 'cursor-fx/react';
|
|
336
|
+
|
|
337
|
+
function App() {
|
|
338
|
+
// Preload images on mount
|
|
339
|
+
useEffect(() => {
|
|
340
|
+
ImageLoader.loadBubbles('/bubbles')
|
|
341
|
+
.then(() => console.log('✓ Bubble images loaded'))
|
|
342
|
+
.catch(err => console.warn('Failed to load bubbles:', err));
|
|
343
|
+
|
|
344
|
+
ImageLoader.loadSnowflakes('/snowflakes')
|
|
345
|
+
.then(() => console.log('✓ Snowflake images loaded'))
|
|
346
|
+
.catch(err => console.warn('Failed to load snowflakes:', err));
|
|
347
|
+
}, []);
|
|
348
|
+
|
|
349
|
+
return <CursorFX effect="bubble" />;
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Vanilla JavaScript Example
|
|
310
354
|
|
|
311
355
|
```javascript
|
|
312
|
-
import { ImageLoader } from 'cursor-fx';
|
|
356
|
+
import { initCursorFX, ImageLoader } from 'cursor-fx/vanilla';
|
|
357
|
+
|
|
358
|
+
// Preload images first
|
|
359
|
+
Promise.all([
|
|
360
|
+
ImageLoader.loadBubbles('/bubbles'),
|
|
361
|
+
ImageLoader.loadSnowflakes('/snowflakes')
|
|
362
|
+
])
|
|
363
|
+
.then(() => {
|
|
364
|
+
console.log('✓ All images loaded');
|
|
365
|
+
|
|
366
|
+
// Initialize effect after images are ready
|
|
367
|
+
const fx = initCursorFX({ effect: 'bubble' });
|
|
368
|
+
})
|
|
369
|
+
.catch(err => {
|
|
370
|
+
console.warn('Failed to load images:', err);
|
|
371
|
+
// Effect will still work with canvas fallback
|
|
372
|
+
const fx = initCursorFX({ effect: 'bubble' });
|
|
373
|
+
});
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### CDN Example
|
|
377
|
+
|
|
378
|
+
```html
|
|
379
|
+
<script src="https://unpkg.com/cursor-fx@latest/dist/cdn/cursor-fx.min.js"></script>
|
|
380
|
+
|
|
381
|
+
<script>
|
|
382
|
+
// Preload images from your server
|
|
383
|
+
CursorFX.ImageLoader.loadBubbles('/bubbles')
|
|
384
|
+
.then(() => {
|
|
385
|
+
// Initialize bubble effect with images
|
|
386
|
+
const fx = CursorFX.initCursorFX({ effect: 'bubble' });
|
|
387
|
+
});
|
|
388
|
+
</script>
|
|
389
|
+
```
|
|
313
390
|
|
|
314
|
-
|
|
315
|
-
await ImageLoader.loadBubbles('/path/to/bubbles');
|
|
316
|
-
await ImageLoader.loadSnowflakes('/path/to/snowflakes');
|
|
391
|
+
### ImageLoader API
|
|
317
392
|
|
|
318
|
-
|
|
319
|
-
|
|
393
|
+
```typescript
|
|
394
|
+
// Load bubble images (expects 3 PNGs in the directory)
|
|
395
|
+
ImageLoader.loadBubbles(basePath?: string): Promise<HTMLImageElement[]>
|
|
396
|
+
|
|
397
|
+
// Load snowflake images (expects 2+ PNGs in the directory)
|
|
398
|
+
ImageLoader.loadSnowflakes(basePath?: string): Promise<HTMLImageElement[]>
|
|
399
|
+
|
|
400
|
+
// Load a single image
|
|
401
|
+
ImageLoader.loadImage(src: string): Promise<HTMLImageElement>
|
|
402
|
+
|
|
403
|
+
// Check if any images are loaded
|
|
404
|
+
ImageLoader.isLoaded(): boolean
|
|
405
|
+
|
|
406
|
+
// Clear all cached images
|
|
407
|
+
ImageLoader.clear(): void
|
|
320
408
|
```
|
|
321
409
|
|
|
410
|
+
**Required file names:**
|
|
411
|
+
- Bubbles: `soap_bubbles_1.png`, `soap_bubble_2.png`, `soap_bubble_3.png`
|
|
412
|
+
- Snowflakes: `snow_flake_1.png`, `snow_flake_2.png`
|
|
413
|
+
|
|
414
|
+
**Fallback Behavior:**
|
|
415
|
+
If images fail to load or aren't preloaded, bubble and snow effects automatically use optimized canvas rendering instead. Your effects will always work!
|
|
416
|
+
|
|
322
417
|
**Included Assets:**
|
|
323
418
|
- 3 bubble variations (~148KB total)
|
|
324
|
-
-
|
|
419
|
+
- 2 snowflake variations (~140KB total)
|
|
325
420
|
|
|
326
|
-
Assets are
|
|
421
|
+
Assets are bundled at `dist/bubbles/` and `dist/snowflakes/`.
|
|
327
422
|
|
|
328
423
|
## 🎨 Customizing Colors
|
|
329
424
|
|
package/dist/core/index.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
export { C as CursorFXEngine } from '../engine-
|
|
2
|
-
import { E as EffectOptions, a as Effect } from '../
|
|
3
|
-
export { d as EffectFunction, c as EngineOptions, P as Particle, b as ParticleConfig } from '../
|
|
4
|
-
export { I as ImageLoader } from '../imageLoader-Bgr5GJIX.mjs';
|
|
1
|
+
export { C as CursorFXEngine } from '../engine-D48zN1W8.mjs';
|
|
2
|
+
import { E as EffectOptions, a as Effect } from '../imageLoader-VUu0PjNk.mjs';
|
|
3
|
+
export { d as EffectFunction, c as EngineOptions, I as ImageLoader, P as Particle, b as ParticleConfig } from '../imageLoader-VUu0PjNk.mjs';
|
|
5
4
|
|
|
6
5
|
declare function randomColor(colors: string[]): string;
|
|
7
6
|
declare function randomRange(min: number, max: number): number;
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
export { C as CursorFXEngine } from '../engine-
|
|
2
|
-
import { E as EffectOptions, a as Effect } from '../
|
|
3
|
-
export { d as EffectFunction, c as EngineOptions, P as Particle, b as ParticleConfig } from '../
|
|
4
|
-
export { I as ImageLoader } from '../imageLoader-Bgr5GJIX.js';
|
|
1
|
+
export { C as CursorFXEngine } from '../engine-OdnQ6Ya5.js';
|
|
2
|
+
import { E as EffectOptions, a as Effect } from '../imageLoader-VUu0PjNk.js';
|
|
3
|
+
export { d as EffectFunction, c as EngineOptions, I as ImageLoader, P as Particle, b as ParticleConfig } from '../imageLoader-VUu0PjNk.js';
|
|
5
4
|
|
|
6
5
|
declare function randomColor(colors: string[]): string;
|
|
7
6
|
declare function randomRange(min: number, max: number): number;
|
|
@@ -66,4 +66,16 @@ declare class Particle {
|
|
|
66
66
|
draw(ctx: CanvasRenderingContext2D): void;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
declare class ImageLoader {
|
|
70
|
+
private static images;
|
|
71
|
+
private static loading;
|
|
72
|
+
static loadImage(src: string): Promise<HTMLImageElement>;
|
|
73
|
+
static loadBubbles(basePath?: string): Promise<HTMLImageElement[]>;
|
|
74
|
+
static loadSnowflakes(basePath?: string): Promise<HTMLImageElement[]>;
|
|
75
|
+
static getRandomBubble(): HTMLImageElement | null;
|
|
76
|
+
static getRandomSnowflake(): HTMLImageElement | null;
|
|
77
|
+
static isLoaded(): boolean;
|
|
78
|
+
static clear(): void;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { type EffectOptions as E, ImageLoader as I, Particle as P, type Effect as a, type ParticleConfig as b, type EngineOptions as c, type EffectFunction as d };
|
|
@@ -66,4 +66,16 @@ declare class Particle {
|
|
|
66
66
|
draw(ctx: CanvasRenderingContext2D): void;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
declare class ImageLoader {
|
|
70
|
+
private static images;
|
|
71
|
+
private static loading;
|
|
72
|
+
static loadImage(src: string): Promise<HTMLImageElement>;
|
|
73
|
+
static loadBubbles(basePath?: string): Promise<HTMLImageElement[]>;
|
|
74
|
+
static loadSnowflakes(basePath?: string): Promise<HTMLImageElement[]>;
|
|
75
|
+
static getRandomBubble(): HTMLImageElement | null;
|
|
76
|
+
static getRandomSnowflake(): HTMLImageElement | null;
|
|
77
|
+
static isLoaded(): boolean;
|
|
78
|
+
static clear(): void;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { type EffectOptions as E, ImageLoader as I, Particle as P, type Effect as a, type ParticleConfig as b, type EngineOptions as c, type EffectFunction as d };
|
package/dist/react/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CursorFXEngine } from '../engine-
|
|
2
|
-
export { E as EffectOptions } from '../
|
|
1
|
+
import { C as CursorFXEngine } from '../engine-D48zN1W8.mjs';
|
|
2
|
+
export { E as EffectOptions, I as ImageLoader } from '../imageLoader-VUu0PjNk.mjs';
|
|
3
3
|
|
|
4
4
|
type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';
|
|
5
5
|
interface UseCursorFXOptions {
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as CursorFXEngine } from '../engine-
|
|
2
|
-
export { E as EffectOptions } from '../
|
|
1
|
+
import { C as CursorFXEngine } from '../engine-OdnQ6Ya5.js';
|
|
2
|
+
export { E as EffectOptions, I as ImageLoader } from '../imageLoader-VUu0PjNk.js';
|
|
3
3
|
|
|
4
4
|
type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';
|
|
5
5
|
interface UseCursorFXOptions {
|
package/dist/react/index.js
CHANGED
|
@@ -773,9 +773,7 @@ function useCursorFX(options = {}) {
|
|
|
773
773
|
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
774
774
|
if (prefersReducedMotion) return;
|
|
775
775
|
const engine = new CursorFXEngine();
|
|
776
|
-
const
|
|
777
|
-
particleCount: 2,
|
|
778
|
-
// Reduced from default 3
|
|
776
|
+
const effectOptions = {
|
|
779
777
|
...memoizedColors && { colors: memoizedColors },
|
|
780
778
|
...particleCount !== void 0 && { particleCount },
|
|
781
779
|
...particleSize !== void 0 && { particleSize },
|
|
@@ -783,7 +781,7 @@ function useCursorFX(options = {}) {
|
|
|
783
781
|
...maxLife !== void 0 && { maxLife },
|
|
784
782
|
...velocity !== void 0 && { velocity }
|
|
785
783
|
};
|
|
786
|
-
const selectedEffect = effect === "confetti" ? createConfettiEffect(
|
|
784
|
+
const selectedEffect = effect === "confetti" ? createConfettiEffect(effectOptions) : effect === "sparkle" ? createSparkleEffect(effectOptions) : effect === "retroCRT" ? createRetroCRTEffect(effectOptions) : effect === "snow" ? createSnowEffect(effectOptions) : effect === "bubble" ? createBubbleEffect(effectOptions) : createFairyDustEffect(effectOptions);
|
|
787
785
|
engine.start(selectedEffect);
|
|
788
786
|
engineRef.current = engine;
|
|
789
787
|
return () => {
|
|
@@ -799,6 +797,7 @@ function CursorFX(props) {
|
|
|
799
797
|
}
|
|
800
798
|
|
|
801
799
|
exports.CursorFX = CursorFX;
|
|
800
|
+
exports.ImageLoader = ImageLoader;
|
|
802
801
|
exports.useCursorFX = useCursorFX;
|
|
803
802
|
//# sourceMappingURL=index.js.map
|
|
804
803
|
//# sourceMappingURL=index.js.map
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/utils.ts","../../src/core/engine.ts","../../src/core/particle.ts","../../src/core/imageLoader.ts","../../src/core/effects/fairyDust.ts","../../src/core/effects/sparkle.ts","../../src/core/effects/confetti.ts","../../src/core/effects/retroCRT.ts","../../src/core/effects/snow.ts","../../src/core/effects/bubble.ts","../../src/react/index.tsx"],"names":["DEFAULT_COLORS","useRef","useMemo","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["export function randomColor(colors: string[]): string {\n return colors[Math.floor(Math.random() * colors.length)];\n}\n\nexport function randomRange(min: number, max: number): number {\n return Math.random() * (max - min) + min;\n}\n\nexport function createCanvas(container: HTMLElement): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n canvas.style.position = 'fixed';\n canvas.style.top = '0';\n canvas.style.left = '0';\n canvas.style.pointerEvents = 'none';\n canvas.style.zIndex = '9999';\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n container.appendChild(canvas);\n return canvas;\n}\n\nexport function resizeCanvas(canvas: HTMLCanvasElement): void {\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n}\n\nexport function drawStar(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n spikes: number = 5\n): void {\n const outerRadius = size;\n const innerRadius = size * 0.4;\n\n ctx.beginPath();\n for (let i = 0; i < spikes * 2; i++) {\n const angle = (i * Math.PI) / spikes;\n const radius = i % 2 === 0 ? outerRadius : innerRadius;\n const dx = Math.cos(angle) * radius;\n const dy = Math.sin(angle) * radius;\n\n if (i === 0) {\n ctx.moveTo(x + dx, y + dy);\n } else {\n ctx.lineTo(x + dx, y + dy);\n }\n }\n ctx.closePath();\n ctx.fill();\n}\n\nexport function drawRectangle(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.fillRect(x - width / 2, y - height / 2, width, height);\n}\n\nexport function drawSnowflake(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n rotation: number = 0\n): void {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n // Optimized glow - reduced blur for better performance\n ctx.shadowBlur = 4;\n ctx.shadowColor = '#FFFFFF';\n ctx.lineWidth = 1.8; // Slightly thicker for better visibility\n\n // Draw all 6 arms in a single path for better performance\n ctx.beginPath();\n for (let i = 0; i < 6; i++) {\n const angle = (i * Math.PI) / 3;\n ctx.moveTo(0, 0);\n ctx.lineTo(Math.cos(angle) * size, Math.sin(angle) * size);\n }\n ctx.stroke();\n\n ctx.restore();\n}\n\nexport function drawBubble(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n): void {\n // Save the original fill color\n const baseColor = ctx.fillStyle as string;\n\n // Main bubble with multi-layer gradient for depth\n const mainGradient = ctx.createRadialGradient(x - size * 0.25, y - size * 0.25, 0, x, y, size);\n mainGradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)');\n mainGradient.addColorStop(0.3, baseColor);\n mainGradient.addColorStop(0.7, baseColor);\n mainGradient.addColorStop(1, 'rgba(255, 255, 255, 0.1)');\n\n ctx.beginPath();\n ctx.arc(x, y, size, 0, Math.PI * 2);\n ctx.fillStyle = mainGradient;\n ctx.fill();\n\n // Subtle border/rim for definition\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';\n ctx.lineWidth = 1;\n ctx.stroke();\n\n // Primary highlight (large, soft)\n ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';\n ctx.beginPath();\n ctx.arc(x - size * 0.3, y - size * 0.3, size * 0.35, 0, Math.PI * 2);\n ctx.fill();\n\n // Secondary highlight (small, bright)\n ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';\n ctx.beginPath();\n ctx.arc(x - size * 0.4, y - size * 0.4, size * 0.15, 0, Math.PI * 2);\n ctx.fill();\n\n // Reflected light on opposite side\n ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';\n ctx.beginPath();\n ctx.arc(x + size * 0.4, y + size * 0.4, size * 0.2, 0, Math.PI * 2);\n ctx.fill();\n}\n\nexport function drawCross(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n): void {\n // Draw simple 4-pointed cross/plus shape\n const halfSize = size / 2;\n const thickness = size * 0.3;\n\n // Vertical bar\n ctx.fillRect(x - thickness / 2, y - halfSize, thickness, size);\n // Horizontal bar\n ctx.fillRect(x - halfSize, y - thickness / 2, size, thickness);\n}\n\nexport function drawOval(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.save();\n ctx.translate(x, y);\n ctx.scale(width / height, 1);\n ctx.beginPath();\n ctx.arc(0, 0, height, 0, Math.PI * 2);\n ctx.fill();\n ctx.restore();\n}\n","import { Particle } from './particle';\nimport { createCanvas, resizeCanvas } from './utils';\nimport type { EngineOptions, Effect } from './types';\n\nexport class CursorFXEngine {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private particles: Particle[] = [];\n private animationId: number | null = null;\n private effect: Effect | null = null;\n private maxParticles: number = 500; // Cap to prevent performance issues\n private lastParticleTime: number = 0;\n private particleThrottle: number = 16; // Create particles every 16ms (~60fps)\n private lastMouseX: number = 0;\n private lastMouseY: number = 0;\n private minMoveDistance: number = 0; // Create particles on every valid move\n\n constructor(options: EngineOptions = {}) {\n if (options.canvas) {\n this.canvas = options.canvas;\n } else {\n const container = options.container || document.body;\n this.canvas = createCanvas(container);\n }\n\n const ctx = this.canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get 2D context');\n }\n this.ctx = ctx;\n\n // Bind methods once to prevent memory leaks\n this.handleResize = this.handleResize.bind(this);\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleTouchMove = this.handleTouchMove.bind(this);\n this.animate = this.animate.bind(this);\n\n window.addEventListener('resize', this.handleResize);\n }\n\n private handleResize(): void {\n resizeCanvas(this.canvas);\n }\n\n private handleMouseMove(e: MouseEvent): void {\n if (!this.effect) return;\n\n const now = Date.now();\n const dx = e.clientX - this.lastMouseX;\n const dy = e.clientY - this.lastMouseY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use effect-specific throttle and move distance if provided\n const throttle = this.effect.throttle ?? this.particleThrottle;\n const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n // Only create particles if enough time passed AND mouse moved enough\n if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n this.lastParticleTime = now;\n this.lastMouseX = e.clientX;\n this.lastMouseY = e.clientY;\n const particles = this.effect.onMouseMove(e.clientX, e.clientY);\n this.addParticles(particles);\n }\n }\n\n private handleTouchMove(e: TouchEvent): void {\n if (!this.effect || e.touches.length === 0) return;\n\n const now = Date.now();\n const touch = e.touches[0];\n const dx = touch.clientX - this.lastMouseX;\n const dy = touch.clientY - this.lastMouseY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use effect-specific throttle and move distance if provided\n const throttle = this.effect.throttle ?? this.particleThrottle;\n const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n // Only create particles if enough time passed AND touch moved enough\n if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n this.lastParticleTime = now;\n this.lastMouseX = touch.clientX;\n this.lastMouseY = touch.clientY;\n const particles = this.effect.onMouseMove(touch.clientX, touch.clientY);\n this.addParticles(particles);\n }\n }\n\n addParticle(particle: Particle): void {\n if (this.particles.length < this.maxParticles) {\n this.particles.push(particle);\n }\n }\n\n addParticles(particles: Particle[]): void {\n const availableSlots = this.maxParticles - this.particles.length;\n if (availableSlots > 0) {\n this.particles.push(...particles.slice(0, availableSlots));\n }\n }\n\n private update(): void {\n // Update all particles\n this.particles.forEach(particle => particle.update());\n // Remove dead particles\n this.particles = this.particles.filter(particle => !particle.isDead());\n }\n\n private draw(): void {\n // Clear canvas\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n // Render all particles with shadow/glow effects\n this.particles.forEach(particle => particle.draw(this.ctx));\n }\n\n private animate(): void {\n this.update();\n this.draw();\n this.animationId = requestAnimationFrame(this.animate);\n }\n\n start(effect: Effect): void {\n if (this.animationId === null) {\n this.effect = effect;\n this.animationId = requestAnimationFrame(this.animate);\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('touchmove', this.handleTouchMove, { passive: true });\n }\n }\n\n stop(): void {\n if (this.animationId !== null) {\n cancelAnimationFrame(this.animationId);\n this.animationId = null;\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('touchmove', this.handleTouchMove);\n }\n }\n\n clear(): void {\n this.particles = [];\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n\n destroy(): void {\n this.stop();\n this.clear();\n window.removeEventListener('resize', this.handleResize);\n if (this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n}\n","import type { ParticleConfig } from './types';\nimport { drawStar, drawRectangle, drawSnowflake, drawBubble, drawCross, drawOval } from './utils';\n\nexport class Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n size: number;\n color: string;\n life: number;\n maxLife: number;\n gravity: number;\n opacity: number;\n rotation: number;\n rotationSpeed: number;\n shape: 'star' | 'rectangle' | 'circle' | 'snowflake' | 'bubble' | 'cross' | 'oval';\n wobbleAmplitude: number;\n wobbleSpeed: number;\n wobblePhase: number;\n windDrift: number;\n image?: HTMLImageElement;\n scale: number;\n initialScale: number;\n scaleUpDuration: number;\n\n constructor(config: ParticleConfig) {\n this.x = config.x;\n this.y = config.y;\n this.vx = config.vx ?? (Math.random() - 0.5) * 4;\n this.vy = config.vy ?? (Math.random() - 0.5) * 4;\n this.size = config.size ?? 3;\n this.color = config.color ?? '#ffffff';\n this.maxLife = config.maxLife ?? 40; // Reduced for better performance\n this.life = 0;\n this.gravity = config.gravity ?? 0.1;\n this.opacity = 1;\n this.rotation = config.rotation ?? 0;\n this.rotationSpeed = config.rotationSpeed ?? 0;\n this.shape = config.shape ?? 'star';\n this.wobbleAmplitude = config.wobbleAmplitude ?? 0;\n this.wobbleSpeed = config.wobbleSpeed ?? 0;\n this.wobblePhase = Math.random() * Math.PI * 2; // Random starting phase\n this.windDrift = config.windDrift ?? 0;\n this.image = config.image;\n this.initialScale = config.initialScale ?? 1; // Default to full scale\n this.scaleUpDuration = config.scaleUpDuration ?? 0; // Default no animation\n this.scale = this.initialScale; // Start at initial scale\n }\n\n update(): void {\n this.life++;\n this.vy += this.gravity;\n\n // Animate scale from initialScale to 1.0 over scaleUpDuration frames\n if (this.scaleUpDuration > 0 && this.life < this.scaleUpDuration) {\n const progress = this.life / this.scaleUpDuration;\n // Ease-out cubic for smooth pop-up effect\n const easedProgress = 1 - Math.pow(1 - progress, 3);\n this.scale = this.initialScale + (1 - this.initialScale) * easedProgress;\n } else {\n this.scale = 1;\n }\n\n // Apply wobble (for bubbles)\n if (this.wobbleAmplitude > 0) {\n this.wobblePhase += this.wobbleSpeed;\n this.x += this.vx + Math.sin(this.wobblePhase) * this.wobbleAmplitude;\n } else {\n this.x += this.vx;\n }\n\n // Apply wind drift (for snowflakes)\n if (this.windDrift > 0) {\n // Smooth Perlin-like drift using sine waves at different frequencies\n const drift = Math.sin(this.life * 0.05) * this.windDrift * 0.3 +\n Math.sin(this.life * 0.02) * this.windDrift * 0.7;\n this.x += drift;\n }\n\n this.y += this.vy;\n this.rotation += this.rotationSpeed;\n this.opacity = 1 - this.life / this.maxLife;\n }\n\n isDead(): boolean {\n return this.life >= this.maxLife;\n }\n\n draw(ctx: CanvasRenderingContext2D): void {\n ctx.save();\n ctx.globalAlpha = this.opacity;\n\n // Apply scale transform (for pop-up animation)\n ctx.translate(this.x, this.y);\n ctx.scale(this.scale, this.scale);\n ctx.translate(-this.x, -this.y);\n\n // If image is available, render image instead of shape\n if (this.image && this.image.complete) {\n // Enable high-quality image smoothing for better rendering\n ctx.imageSmoothingEnabled = true;\n ctx.imageSmoothingQuality = 'high';\n\n const imgSize = this.size * 2.5; // Larger multiplier for bigger images\n ctx.translate(this.x, this.y);\n if (this.rotation !== 0) {\n ctx.rotate(this.rotation);\n }\n\n // Add simple glow for snowflake images (single pass)\n // if (this.shape === 'snowflake') {\n // ctx.shadowBlur = 8;\n // ctx.shadowColor = '#FFFFFF';\n // }\n\n ctx.drawImage(\n this.image,\n -imgSize / 2,\n -imgSize / 2,\n imgSize,\n imgSize\n );\n ctx.restore();\n return;\n }\n\n // Fallback to shape rendering\n ctx.fillStyle = this.color;\n\n // Draw based on shape\n switch (this.shape) {\n case 'rectangle':\n if (this.rotation !== 0) {\n ctx.translate(this.x, this.y);\n ctx.rotate(this.rotation);\n ctx.translate(-this.x, -this.y);\n }\n drawRectangle(ctx, this.x, this.y, this.size, this.size * 1.5);\n break;\n\n case 'circle':\n ctx.shadowBlur = 15; // Strong glow for circles\n ctx.shadowColor = this.color;\n ctx.beginPath();\n ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);\n ctx.fill();\n break;\n\n case 'snowflake':\n ctx.strokeStyle = this.color;\n ctx.lineWidth = 1.5;\n drawSnowflake(ctx, this.x, this.y, this.size, this.rotation);\n break;\n\n case 'bubble':\n drawBubble(ctx, this.x, this.y, this.size);\n break;\n\n case 'cross':\n ctx.shadowBlur = 18; // Strong glow for fairy dust\n ctx.shadowColor = this.color;\n drawCross(ctx, this.x, this.y, this.size);\n break;\n\n case 'oval':\n ctx.shadowBlur = 12; // Moderate glow for CRT phosphor\n ctx.shadowColor = this.color;\n drawOval(ctx, this.x, this.y, this.size * 2, this.size);\n break;\n\n default: // star\n drawStar(ctx, this.x, this.y, this.size, 5);\n break;\n }\n\n ctx.restore();\n }\n}\n","// Image loader for bubble assets\nexport class ImageLoader {\n private static images: Map<string, HTMLImageElement> = new Map();\n private static loading: Map<string, Promise<HTMLImageElement>> = new Map();\n\n static async loadImage(src: string): Promise<HTMLImageElement> {\n // Return cached image if already loaded\n if (this.images.has(src)) {\n return this.images.get(src)!;\n }\n\n // Return existing promise if currently loading\n if (this.loading.has(src)) {\n return this.loading.get(src)!;\n }\n\n // Create new loading promise\n const loadPromise = new Promise<HTMLImageElement>((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n this.images.set(src, img);\n this.loading.delete(src);\n resolve(img);\n };\n img.onerror = () => {\n this.loading.delete(src);\n reject(new Error(`Failed to load image: ${src}`));\n };\n img.src = src;\n });\n\n this.loading.set(src, loadPromise);\n return loadPromise;\n }\n\n static async loadBubbles(basePath: string = '/bubbles'): Promise<HTMLImageElement[]> {\n const bubblePaths = [\n `${basePath}/soap_bubbles_1.png`,\n `${basePath}/soap_bubble_2.png`,\n `${basePath}/soap_bubble_3.png`,\n ];\n\n try {\n return await Promise.all(bubblePaths.map(path => this.loadImage(path)));\n } catch (error) {\n console.warn('Failed to load some bubble images, falling back to canvas rendering', error);\n return [];\n }\n }\n\n static async loadSnowflakes(basePath: string = '/snowflakes'): Promise<HTMLImageElement[]> {\n const snowflakePaths = [\n // `${basePath}/snowflake.png`,\n `${basePath}/snow_flake_1.png`,\n `${basePath}/snow_flake_2.png`,\n ];\n\n try {\n return await Promise.all(snowflakePaths.map(path => this.loadImage(path)));\n } catch (error) {\n console.warn('Failed to load some snowflake images, falling back to canvas rendering', error);\n return [];\n }\n }\n\n static getRandomBubble(): HTMLImageElement | null {\n const bubbleImages = Array.from(this.images.entries())\n .filter(([key]) => key.includes('bubble'))\n .map(([, img]) => img);\n if (bubbleImages.length === 0) return null;\n return bubbleImages[Math.floor(Math.random() * bubbleImages.length)];\n }\n\n static getRandomSnowflake(): HTMLImageElement | null {\n const snowflakeImages = Array.from(this.images.entries())\n .filter(([key]) => key.includes('snow'))\n .map(([, img]) => img);\n if (snowflakeImages.length === 0) return null;\n return snowflakeImages[Math.floor(Math.random() * snowflakeImages.length)];\n }\n\n static isLoaded(): boolean {\n return this.images.size > 0;\n }\n\n static clear(): void {\n this.images.clear();\n this.loading.clear();\n }\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFD700', // Gold\n '#FFC700', // Golden Yellow\n '#FFB700', // Amber\n '#FFED4E', // Light Gold\n '#F4E04D', // Pale Gold\n];\n\nexport function createFairyDustEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 2,\n particleSize = 6, // Increased from 4 for better visibility\n gravity = -0.05, // Slight upward float for magical feel\n maxLife = 40,\n velocity = 3,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 15,\n y: y + (Math.random() - 0.5) * 15,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity - 1, // Slight upward bias\n size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 20,\n gravity,\n shape: 'cross',\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFD700', // Gold\n '#FF69B4', // Hot Pink\n '#00CED1', // Dark Turquoise\n '#9370DB', // Medium Purple\n];\n\nexport function createSparkleEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // Reduced for better performance\n particleSize = 6, // Increased from 3 for better visibility\n gravity = 0.1,\n maxLife = 20, // Further reduced for faster cleanup\n velocity = 4,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 10,\n y: y + (Math.random() - 0.5) * 10,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity,\n size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 10, // Reduced random variation\n gravity,\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FF6B6B', // Red\n '#4ECDC4', // Turquoise\n '#FFE66D', // Yellow\n '#95E1D3', // Mint\n '#F38181', // Pink\n '#AA96DA', // Purple\n '#FCBAD3', // Light Pink\n '#A8D8EA', // Sky Blue\n];\n\nexport function createConfettiEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 3,\n particleSize = 4,\n gravity = 0.3, // Stronger gravity for falling effect\n maxLife = 60, // Longer lifetime for confetti\n velocity = 6,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 20,\n y: y + (Math.random() - 0.5) * 20,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 1) * velocity * 0.5, // Bias upward initially\n size: Math.random() * particleSize + 3,\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 20,\n gravity,\n rotation: Math.random() * Math.PI * 2, // Random initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.2, // Rotation speed\n shape: 'rectangle',\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#00FF00', // Classic phosphor green\n '#33FF33', // Bright phosphor green\n '#00CC00', // Medium phosphor green\n '#00DD00', // Light phosphor green\n];\n\nexport function createRetroCRTEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 3,\n particleSize = 4, // Slightly larger for better visibility\n gravity = 0, // No gravity - phosphor glows in place\n maxLife = 60, // Longer persistence like real phosphor\n velocity = 1, // Very slow movement for authentic glow\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 8,\n y: y + (Math.random() - 0.5) * 8,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity,\n size: Math.random() * particleSize + 2,\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 15,\n gravity,\n shape: 'circle', // Back to circles with strong glow\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFFFFF', // Pure white\n '#F0F8FF', // Alice blue\n '#E6F3FF', // Light blue white\n '#F5F5F5', // White smoke\n];\n\n// ⚙️ CONFIGURATION FLAG: Switch between image-based and canvas-drawn snowflakes\nconst USE_SNOWFLAKE_IMAGES = true; // Set to true to use PNG images, false for canvas drawing\n\nexport function createSnowEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // One snowflake at a time\n particleSize = 7, // Bigger for better visibility\n gravity = 0.12, // Faster falling\n maxLife = 150, // Shorter lifetime for faster fall\n velocity = 0.4, // Slightly more drift\n throttle = 120, // Spawn every 120ms - less frequent\n minMoveDistance = 12, // Only spawn when cursor moves 12px\n } = options;\n\n return {\n throttle,\n minMoveDistance,\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n // Conditionally get snowflake image based on flag\n const snowflakeImage = USE_SNOWFLAKE_IMAGES ? ImageLoader.getRandomSnowflake() : null;\n\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 30,\n y: y + (Math.random() - 0.5) * 15,\n vx: (Math.random() - 0.5) * velocity,\n vy: Math.random() * 0.2 + 0.1, // Slightly faster downward initial velocity\n size: Math.random() * particleSize + 3, // Variable sizes (3-10px for canvas, base for images)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 60,\n gravity,\n rotation: Math.random() * Math.PI * 2, // Random initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.03, // More visible rotation\n shape: 'snowflake',\n windDrift: 0.8, // Gentle wind drift/sway\n image: snowflakeImage || undefined, // Use image if flag is true and images loaded\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n 'rgba(173, 216, 230, 0.4)', // Light blue - transparent\n 'rgba(135, 206, 235, 0.4)', // Sky blue - transparent\n 'rgba(176, 224, 230, 0.4)', // Powder blue - transparent\n 'rgba(175, 238, 238, 0.4)', // Pale turquoise - transparent\n 'rgba(224, 255, 255, 0.4)', // Light cyan - transparent\n];\n\nexport function createBubbleEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // Spawn one bubble at a time\n gravity = -0.02, // Gentle upward buoyancy\n maxLife = 180, // Longer lifetime for slow rise\n velocity = 0.2, // Minimal base horizontal drift\n throttle = 150, // Spawn every 150ms - much less frequent\n minMoveDistance = 15, // Only spawn when cursor moves 15px\n } = options;\n\n return {\n throttle,\n minMoveDistance,\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n const bubbleImage = ImageLoader.getRandomBubble();\n\n // Create more dramatic size variation (15-45 range for 2.5x multiplier = 37-112px actual)\n const baseSize = 15 + Math.random() * 30;\n\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 10, // Spawn closer to pointer\n y: y + (Math.random() - 0.5) * 10,\n vx: (Math.random() - 0.5) * velocity,\n vy: -Math.random() * 0.15 - 0.1, // Very slow, consistent upward\n size: baseSize, // Wide size variation (15-45)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 60,\n gravity,\n shape: 'bubble',\n wobbleAmplitude: 0.3, // Gentle horizontal wobble\n wobbleSpeed: 0.05, // Slow wobble oscillation\n image: bubbleImage || undefined, // Use image if loaded, fallback to canvas\n initialScale: 0.3, // Start at 30% size for pop-up effect\n scaleUpDuration: 15, // Grow to full size over 15 frames (~250ms)\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { useEffect, useRef, useMemo } from 'react';\nimport { CursorFXEngine, createFairyDustEffect, createSparkleEffect, createConfettiEffect, createRetroCRTEffect, createSnowEffect, createBubbleEffect } from '../core';\n\nexport type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';\n\nexport interface UseCursorFXOptions {\n effect?: CursorEffectType;\n colors?: string[];\n particleCount?: number;\n particleSize?: number;\n gravity?: number;\n maxLife?: number;\n velocity?: number;\n enabled?: boolean;\n}\n\n/**\n * React hook for cursor effects.\n * Returns a ref to attach to your canvas element.\n *\n * @param options - Configuration options for the effect\n * @returns Canvas ref to attach to <canvas> element\n *\n * @example\n * ```tsx\n * function App() {\n * useCursorFX({\n * colors: ['#FFD700', '#FF69B4'],\n * particleCount: 5\n * });\n *\n * return <div>Your content</div>;\n * }\n * ```\n */\nexport function useCursorFX(options: UseCursorFXOptions = {}) {\n const {\n enabled = true,\n effect = 'fairyDust',\n colors,\n particleCount,\n particleSize,\n gravity,\n maxLife,\n velocity\n } = options;\n const engineRef = useRef<CursorFXEngine | null>(null);\n\n // Memoize colors array to prevent unnecessary re-renders when passed inline\n const memoizedColors = useMemo(() => colors, [colors ? JSON.stringify(colors) : undefined]);\n\n useEffect(() => {\n // SSR safety check\n if (typeof window === 'undefined') return;\n if (!enabled) return;\n\n // Check for prefers-reduced-motion\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) return;\n\n // Create engine (automatically creates canvas)\n const engine = new CursorFXEngine();\n\n // Reduce particle count for better performance\n const optimizedOptions = {\n particleCount: 2, // Reduced from default 3\n ...(memoizedColors && { colors: memoizedColors }),\n ...(particleCount !== undefined && { particleCount }),\n ...(particleSize !== undefined && { particleSize }),\n ...(gravity !== undefined && { gravity }),\n ...(maxLife !== undefined && { maxLife }),\n ...(velocity !== undefined && { velocity }),\n };\n\n // Select effect based on type\n const selectedEffect =\n effect === 'confetti'\n ? createConfettiEffect(optimizedOptions)\n : effect === 'sparkle'\n ? createSparkleEffect(optimizedOptions)\n : effect === 'retroCRT'\n ? createRetroCRTEffect(optimizedOptions)\n : effect === 'snow'\n ? createSnowEffect(optimizedOptions)\n : effect === 'bubble'\n ? createBubbleEffect(optimizedOptions)\n : createFairyDustEffect(optimizedOptions);\n\n // Start the effect\n engine.start(selectedEffect);\n engineRef.current = engine;\n\n // Cleanup on unmount\n return () => {\n engine.destroy();\n engineRef.current = null;\n };\n }, [enabled, effect, memoizedColors, particleCount, particleSize, gravity, maxLife, velocity]);\n\n return engineRef.current;\n}\n\n/**\n * CursorFX component for React.\n * Simple wrapper over useCursorFX hook.\n *\n * @param props - Configuration options for the effect\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <>\n * <CursorFX\n * colors={['#FFD700', '#FF69B4']}\n * particleCount={5}\n * />\n * <YourContent />\n * </>\n * );\n * }\n * ```\n */\nexport function CursorFX(props: UseCursorFXOptions) {\n useCursorFX(props);\n return null;\n}\n\n// Export types for TypeScript users\nexport type { EffectOptions } from '../core/types';\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/utils.ts","../../src/core/engine.ts","../../src/core/particle.ts","../../src/core/imageLoader.ts","../../src/core/effects/fairyDust.ts","../../src/core/effects/sparkle.ts","../../src/core/effects/confetti.ts","../../src/core/effects/retroCRT.ts","../../src/core/effects/snow.ts","../../src/core/effects/bubble.ts","../../src/react/index.tsx"],"names":["DEFAULT_COLORS","useRef","useMemo","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["export function randomColor(colors: string[]): string {\n return colors[Math.floor(Math.random() * colors.length)];\n}\n\nexport function randomRange(min: number, max: number): number {\n return Math.random() * (max - min) + min;\n}\n\nexport function createCanvas(container: HTMLElement): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n canvas.style.position = 'fixed';\n canvas.style.top = '0';\n canvas.style.left = '0';\n canvas.style.pointerEvents = 'none';\n canvas.style.zIndex = '9999';\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n container.appendChild(canvas);\n return canvas;\n}\n\nexport function resizeCanvas(canvas: HTMLCanvasElement): void {\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n}\n\nexport function drawStar(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n spikes: number = 5\n): void {\n const outerRadius = size;\n const innerRadius = size * 0.4;\n\n ctx.beginPath();\n for (let i = 0; i < spikes * 2; i++) {\n const angle = (i * Math.PI) / spikes;\n const radius = i % 2 === 0 ? outerRadius : innerRadius;\n const dx = Math.cos(angle) * radius;\n const dy = Math.sin(angle) * radius;\n\n if (i === 0) {\n ctx.moveTo(x + dx, y + dy);\n } else {\n ctx.lineTo(x + dx, y + dy);\n }\n }\n ctx.closePath();\n ctx.fill();\n}\n\nexport function drawRectangle(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.fillRect(x - width / 2, y - height / 2, width, height);\n}\n\nexport function drawSnowflake(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number,\n rotation: number = 0\n): void {\n ctx.save();\n ctx.translate(x, y);\n ctx.rotate(rotation);\n\n // Optimized glow - reduced blur for better performance\n ctx.shadowBlur = 4;\n ctx.shadowColor = '#FFFFFF';\n ctx.lineWidth = 1.8; // Slightly thicker for better visibility\n\n // Draw all 6 arms in a single path for better performance\n ctx.beginPath();\n for (let i = 0; i < 6; i++) {\n const angle = (i * Math.PI) / 3;\n ctx.moveTo(0, 0);\n ctx.lineTo(Math.cos(angle) * size, Math.sin(angle) * size);\n }\n ctx.stroke();\n\n ctx.restore();\n}\n\nexport function drawBubble(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n): void {\n // Save the original fill color\n const baseColor = ctx.fillStyle as string;\n\n // Main bubble with multi-layer gradient for depth\n const mainGradient = ctx.createRadialGradient(x - size * 0.25, y - size * 0.25, 0, x, y, size);\n mainGradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)');\n mainGradient.addColorStop(0.3, baseColor);\n mainGradient.addColorStop(0.7, baseColor);\n mainGradient.addColorStop(1, 'rgba(255, 255, 255, 0.1)');\n\n ctx.beginPath();\n ctx.arc(x, y, size, 0, Math.PI * 2);\n ctx.fillStyle = mainGradient;\n ctx.fill();\n\n // Subtle border/rim for definition\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';\n ctx.lineWidth = 1;\n ctx.stroke();\n\n // Primary highlight (large, soft)\n ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';\n ctx.beginPath();\n ctx.arc(x - size * 0.3, y - size * 0.3, size * 0.35, 0, Math.PI * 2);\n ctx.fill();\n\n // Secondary highlight (small, bright)\n ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';\n ctx.beginPath();\n ctx.arc(x - size * 0.4, y - size * 0.4, size * 0.15, 0, Math.PI * 2);\n ctx.fill();\n\n // Reflected light on opposite side\n ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';\n ctx.beginPath();\n ctx.arc(x + size * 0.4, y + size * 0.4, size * 0.2, 0, Math.PI * 2);\n ctx.fill();\n}\n\nexport function drawCross(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n size: number\n): void {\n // Draw simple 4-pointed cross/plus shape\n const halfSize = size / 2;\n const thickness = size * 0.3;\n\n // Vertical bar\n ctx.fillRect(x - thickness / 2, y - halfSize, thickness, size);\n // Horizontal bar\n ctx.fillRect(x - halfSize, y - thickness / 2, size, thickness);\n}\n\nexport function drawOval(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number\n): void {\n ctx.save();\n ctx.translate(x, y);\n ctx.scale(width / height, 1);\n ctx.beginPath();\n ctx.arc(0, 0, height, 0, Math.PI * 2);\n ctx.fill();\n ctx.restore();\n}\n","import { Particle } from './particle';\nimport { createCanvas, resizeCanvas } from './utils';\nimport type { EngineOptions, Effect } from './types';\n\nexport class CursorFXEngine {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private particles: Particle[] = [];\n private animationId: number | null = null;\n private effect: Effect | null = null;\n private maxParticles: number = 500; // Cap to prevent performance issues\n private lastParticleTime: number = 0;\n private particleThrottle: number = 16; // Create particles every 16ms (~60fps)\n private lastMouseX: number = 0;\n private lastMouseY: number = 0;\n private minMoveDistance: number = 0; // Create particles on every valid move\n\n constructor(options: EngineOptions = {}) {\n if (options.canvas) {\n this.canvas = options.canvas;\n } else {\n const container = options.container || document.body;\n this.canvas = createCanvas(container);\n }\n\n const ctx = this.canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get 2D context');\n }\n this.ctx = ctx;\n\n // Bind methods once to prevent memory leaks\n this.handleResize = this.handleResize.bind(this);\n this.handleMouseMove = this.handleMouseMove.bind(this);\n this.handleTouchMove = this.handleTouchMove.bind(this);\n this.animate = this.animate.bind(this);\n\n window.addEventListener('resize', this.handleResize);\n }\n\n private handleResize(): void {\n resizeCanvas(this.canvas);\n }\n\n private handleMouseMove(e: MouseEvent): void {\n if (!this.effect) return;\n\n const now = Date.now();\n const dx = e.clientX - this.lastMouseX;\n const dy = e.clientY - this.lastMouseY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use effect-specific throttle and move distance if provided\n const throttle = this.effect.throttle ?? this.particleThrottle;\n const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n // Only create particles if enough time passed AND mouse moved enough\n if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n this.lastParticleTime = now;\n this.lastMouseX = e.clientX;\n this.lastMouseY = e.clientY;\n const particles = this.effect.onMouseMove(e.clientX, e.clientY);\n this.addParticles(particles);\n }\n }\n\n private handleTouchMove(e: TouchEvent): void {\n if (!this.effect || e.touches.length === 0) return;\n\n const now = Date.now();\n const touch = e.touches[0];\n const dx = touch.clientX - this.lastMouseX;\n const dy = touch.clientY - this.lastMouseY;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // Use effect-specific throttle and move distance if provided\n const throttle = this.effect.throttle ?? this.particleThrottle;\n const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n // Only create particles if enough time passed AND touch moved enough\n if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n this.lastParticleTime = now;\n this.lastMouseX = touch.clientX;\n this.lastMouseY = touch.clientY;\n const particles = this.effect.onMouseMove(touch.clientX, touch.clientY);\n this.addParticles(particles);\n }\n }\n\n addParticle(particle: Particle): void {\n if (this.particles.length < this.maxParticles) {\n this.particles.push(particle);\n }\n }\n\n addParticles(particles: Particle[]): void {\n const availableSlots = this.maxParticles - this.particles.length;\n if (availableSlots > 0) {\n this.particles.push(...particles.slice(0, availableSlots));\n }\n }\n\n private update(): void {\n // Update all particles\n this.particles.forEach(particle => particle.update());\n // Remove dead particles\n this.particles = this.particles.filter(particle => !particle.isDead());\n }\n\n private draw(): void {\n // Clear canvas\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n // Render all particles with shadow/glow effects\n this.particles.forEach(particle => particle.draw(this.ctx));\n }\n\n private animate(): void {\n this.update();\n this.draw();\n this.animationId = requestAnimationFrame(this.animate);\n }\n\n start(effect: Effect): void {\n if (this.animationId === null) {\n this.effect = effect;\n this.animationId = requestAnimationFrame(this.animate);\n document.addEventListener('mousemove', this.handleMouseMove);\n document.addEventListener('touchmove', this.handleTouchMove, { passive: true });\n }\n }\n\n stop(): void {\n if (this.animationId !== null) {\n cancelAnimationFrame(this.animationId);\n this.animationId = null;\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('touchmove', this.handleTouchMove);\n }\n }\n\n clear(): void {\n this.particles = [];\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n\n destroy(): void {\n this.stop();\n this.clear();\n window.removeEventListener('resize', this.handleResize);\n if (this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n}\n","import type { ParticleConfig } from './types';\nimport { drawStar, drawRectangle, drawSnowflake, drawBubble, drawCross, drawOval } from './utils';\n\nexport class Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n size: number;\n color: string;\n life: number;\n maxLife: number;\n gravity: number;\n opacity: number;\n rotation: number;\n rotationSpeed: number;\n shape: 'star' | 'rectangle' | 'circle' | 'snowflake' | 'bubble' | 'cross' | 'oval';\n wobbleAmplitude: number;\n wobbleSpeed: number;\n wobblePhase: number;\n windDrift: number;\n image?: HTMLImageElement;\n scale: number;\n initialScale: number;\n scaleUpDuration: number;\n\n constructor(config: ParticleConfig) {\n this.x = config.x;\n this.y = config.y;\n this.vx = config.vx ?? (Math.random() - 0.5) * 4;\n this.vy = config.vy ?? (Math.random() - 0.5) * 4;\n this.size = config.size ?? 3;\n this.color = config.color ?? '#ffffff';\n this.maxLife = config.maxLife ?? 40; // Reduced for better performance\n this.life = 0;\n this.gravity = config.gravity ?? 0.1;\n this.opacity = 1;\n this.rotation = config.rotation ?? 0;\n this.rotationSpeed = config.rotationSpeed ?? 0;\n this.shape = config.shape ?? 'star';\n this.wobbleAmplitude = config.wobbleAmplitude ?? 0;\n this.wobbleSpeed = config.wobbleSpeed ?? 0;\n this.wobblePhase = Math.random() * Math.PI * 2; // Random starting phase\n this.windDrift = config.windDrift ?? 0;\n this.image = config.image;\n this.initialScale = config.initialScale ?? 1; // Default to full scale\n this.scaleUpDuration = config.scaleUpDuration ?? 0; // Default no animation\n this.scale = this.initialScale; // Start at initial scale\n }\n\n update(): void {\n this.life++;\n this.vy += this.gravity;\n\n // Animate scale from initialScale to 1.0 over scaleUpDuration frames\n if (this.scaleUpDuration > 0 && this.life < this.scaleUpDuration) {\n const progress = this.life / this.scaleUpDuration;\n // Ease-out cubic for smooth pop-up effect\n const easedProgress = 1 - Math.pow(1 - progress, 3);\n this.scale = this.initialScale + (1 - this.initialScale) * easedProgress;\n } else {\n this.scale = 1;\n }\n\n // Apply wobble (for bubbles)\n if (this.wobbleAmplitude > 0) {\n this.wobblePhase += this.wobbleSpeed;\n this.x += this.vx + Math.sin(this.wobblePhase) * this.wobbleAmplitude;\n } else {\n this.x += this.vx;\n }\n\n // Apply wind drift (for snowflakes)\n if (this.windDrift > 0) {\n // Smooth Perlin-like drift using sine waves at different frequencies\n const drift = Math.sin(this.life * 0.05) * this.windDrift * 0.3 +\n Math.sin(this.life * 0.02) * this.windDrift * 0.7;\n this.x += drift;\n }\n\n this.y += this.vy;\n this.rotation += this.rotationSpeed;\n this.opacity = 1 - this.life / this.maxLife;\n }\n\n isDead(): boolean {\n return this.life >= this.maxLife;\n }\n\n draw(ctx: CanvasRenderingContext2D): void {\n ctx.save();\n ctx.globalAlpha = this.opacity;\n\n // Apply scale transform (for pop-up animation)\n ctx.translate(this.x, this.y);\n ctx.scale(this.scale, this.scale);\n ctx.translate(-this.x, -this.y);\n\n // If image is available, render image instead of shape\n if (this.image && this.image.complete) {\n // Enable high-quality image smoothing for better rendering\n ctx.imageSmoothingEnabled = true;\n ctx.imageSmoothingQuality = 'high';\n\n const imgSize = this.size * 2.5; // Larger multiplier for bigger images\n ctx.translate(this.x, this.y);\n if (this.rotation !== 0) {\n ctx.rotate(this.rotation);\n }\n\n // Add simple glow for snowflake images (single pass)\n // if (this.shape === 'snowflake') {\n // ctx.shadowBlur = 8;\n // ctx.shadowColor = '#FFFFFF';\n // }\n\n ctx.drawImage(\n this.image,\n -imgSize / 2,\n -imgSize / 2,\n imgSize,\n imgSize\n );\n ctx.restore();\n return;\n }\n\n // Fallback to shape rendering\n ctx.fillStyle = this.color;\n\n // Draw based on shape\n switch (this.shape) {\n case 'rectangle':\n if (this.rotation !== 0) {\n ctx.translate(this.x, this.y);\n ctx.rotate(this.rotation);\n ctx.translate(-this.x, -this.y);\n }\n drawRectangle(ctx, this.x, this.y, this.size, this.size * 1.5);\n break;\n\n case 'circle':\n ctx.shadowBlur = 15; // Strong glow for circles\n ctx.shadowColor = this.color;\n ctx.beginPath();\n ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);\n ctx.fill();\n break;\n\n case 'snowflake':\n ctx.strokeStyle = this.color;\n ctx.lineWidth = 1.5;\n drawSnowflake(ctx, this.x, this.y, this.size, this.rotation);\n break;\n\n case 'bubble':\n drawBubble(ctx, this.x, this.y, this.size);\n break;\n\n case 'cross':\n ctx.shadowBlur = 18; // Strong glow for fairy dust\n ctx.shadowColor = this.color;\n drawCross(ctx, this.x, this.y, this.size);\n break;\n\n case 'oval':\n ctx.shadowBlur = 12; // Moderate glow for CRT phosphor\n ctx.shadowColor = this.color;\n drawOval(ctx, this.x, this.y, this.size * 2, this.size);\n break;\n\n default: // star\n drawStar(ctx, this.x, this.y, this.size, 5);\n break;\n }\n\n ctx.restore();\n }\n}\n","// Image loader for bubble assets\nexport class ImageLoader {\n private static images: Map<string, HTMLImageElement> = new Map();\n private static loading: Map<string, Promise<HTMLImageElement>> = new Map();\n\n static async loadImage(src: string): Promise<HTMLImageElement> {\n // Return cached image if already loaded\n if (this.images.has(src)) {\n return this.images.get(src)!;\n }\n\n // Return existing promise if currently loading\n if (this.loading.has(src)) {\n return this.loading.get(src)!;\n }\n\n // Create new loading promise\n const loadPromise = new Promise<HTMLImageElement>((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n this.images.set(src, img);\n this.loading.delete(src);\n resolve(img);\n };\n img.onerror = () => {\n this.loading.delete(src);\n reject(new Error(`Failed to load image: ${src}`));\n };\n img.src = src;\n });\n\n this.loading.set(src, loadPromise);\n return loadPromise;\n }\n\n static async loadBubbles(basePath: string = '/bubbles'): Promise<HTMLImageElement[]> {\n const bubblePaths = [\n `${basePath}/soap_bubbles_1.png`,\n `${basePath}/soap_bubble_2.png`,\n `${basePath}/soap_bubble_3.png`,\n ];\n\n try {\n return await Promise.all(bubblePaths.map(path => this.loadImage(path)));\n } catch (error) {\n console.warn('Failed to load some bubble images, falling back to canvas rendering', error);\n return [];\n }\n }\n\n static async loadSnowflakes(basePath: string = '/snowflakes'): Promise<HTMLImageElement[]> {\n const snowflakePaths = [\n // `${basePath}/snowflake.png`,\n `${basePath}/snow_flake_1.png`,\n `${basePath}/snow_flake_2.png`,\n ];\n\n try {\n return await Promise.all(snowflakePaths.map(path => this.loadImage(path)));\n } catch (error) {\n console.warn('Failed to load some snowflake images, falling back to canvas rendering', error);\n return [];\n }\n }\n\n static getRandomBubble(): HTMLImageElement | null {\n const bubbleImages = Array.from(this.images.entries())\n .filter(([key]) => key.includes('bubble'))\n .map(([, img]) => img);\n if (bubbleImages.length === 0) return null;\n return bubbleImages[Math.floor(Math.random() * bubbleImages.length)];\n }\n\n static getRandomSnowflake(): HTMLImageElement | null {\n const snowflakeImages = Array.from(this.images.entries())\n .filter(([key]) => key.includes('snow'))\n .map(([, img]) => img);\n if (snowflakeImages.length === 0) return null;\n return snowflakeImages[Math.floor(Math.random() * snowflakeImages.length)];\n }\n\n static isLoaded(): boolean {\n return this.images.size > 0;\n }\n\n static clear(): void {\n this.images.clear();\n this.loading.clear();\n }\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFD700', // Gold\n '#FFC700', // Golden Yellow\n '#FFB700', // Amber\n '#FFED4E', // Light Gold\n '#F4E04D', // Pale Gold\n];\n\nexport function createFairyDustEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 2,\n particleSize = 6, // Increased from 4 for better visibility\n gravity = -0.05, // Slight upward float for magical feel\n maxLife = 40,\n velocity = 3,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 15,\n y: y + (Math.random() - 0.5) * 15,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity - 1, // Slight upward bias\n size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 20,\n gravity,\n shape: 'cross',\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFD700', // Gold\n '#FF69B4', // Hot Pink\n '#00CED1', // Dark Turquoise\n '#9370DB', // Medium Purple\n];\n\nexport function createSparkleEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // Reduced for better performance\n particleSize = 6, // Increased from 3 for better visibility\n gravity = 0.1,\n maxLife = 20, // Further reduced for faster cleanup\n velocity = 4,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 10,\n y: y + (Math.random() - 0.5) * 10,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity,\n size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 10, // Reduced random variation\n gravity,\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FF6B6B', // Red\n '#4ECDC4', // Turquoise\n '#FFE66D', // Yellow\n '#95E1D3', // Mint\n '#F38181', // Pink\n '#AA96DA', // Purple\n '#FCBAD3', // Light Pink\n '#A8D8EA', // Sky Blue\n];\n\nexport function createConfettiEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 3,\n particleSize = 4,\n gravity = 0.3, // Stronger gravity for falling effect\n maxLife = 60, // Longer lifetime for confetti\n velocity = 6,\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 20,\n y: y + (Math.random() - 0.5) * 20,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 1) * velocity * 0.5, // Bias upward initially\n size: Math.random() * particleSize + 3,\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 20,\n gravity,\n rotation: Math.random() * Math.PI * 2, // Random initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.2, // Rotation speed\n shape: 'rectangle',\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#00FF00', // Classic phosphor green\n '#33FF33', // Bright phosphor green\n '#00CC00', // Medium phosphor green\n '#00DD00', // Light phosphor green\n];\n\nexport function createRetroCRTEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 3,\n particleSize = 4, // Slightly larger for better visibility\n gravity = 0, // No gravity - phosphor glows in place\n maxLife = 60, // Longer persistence like real phosphor\n velocity = 1, // Very slow movement for authentic glow\n } = options;\n\n return {\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 8,\n y: y + (Math.random() - 0.5) * 8,\n vx: (Math.random() - 0.5) * velocity,\n vy: (Math.random() - 0.5) * velocity,\n size: Math.random() * particleSize + 2,\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 15,\n gravity,\n shape: 'circle', // Back to circles with strong glow\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n '#FFFFFF', // Pure white\n '#F0F8FF', // Alice blue\n '#E6F3FF', // Light blue white\n '#F5F5F5', // White smoke\n];\n\n// ⚙️ CONFIGURATION FLAG: Switch between image-based and canvas-drawn snowflakes\nconst USE_SNOWFLAKE_IMAGES = true; // Set to true to use PNG images, false for canvas drawing\n\nexport function createSnowEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // One snowflake at a time\n particleSize = 7, // Bigger for better visibility\n gravity = 0.12, // Faster falling\n maxLife = 150, // Shorter lifetime for faster fall\n velocity = 0.4, // Slightly more drift\n throttle = 120, // Spawn every 120ms - less frequent\n minMoveDistance = 12, // Only spawn when cursor moves 12px\n } = options;\n\n return {\n throttle,\n minMoveDistance,\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n // Conditionally get snowflake image based on flag\n const snowflakeImage = USE_SNOWFLAKE_IMAGES ? ImageLoader.getRandomSnowflake() : null;\n\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 30,\n y: y + (Math.random() - 0.5) * 15,\n vx: (Math.random() - 0.5) * velocity,\n vy: Math.random() * 0.2 + 0.1, // Slightly faster downward initial velocity\n size: Math.random() * particleSize + 3, // Variable sizes (3-10px for canvas, base for images)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 60,\n gravity,\n rotation: Math.random() * Math.PI * 2, // Random initial rotation\n rotationSpeed: (Math.random() - 0.5) * 0.03, // More visible rotation\n shape: 'snowflake',\n windDrift: 0.8, // Gentle wind drift/sway\n image: snowflakeImage || undefined, // Use image if flag is true and images loaded\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n 'rgba(173, 216, 230, 0.4)', // Light blue - transparent\n 'rgba(135, 206, 235, 0.4)', // Sky blue - transparent\n 'rgba(176, 224, 230, 0.4)', // Powder blue - transparent\n 'rgba(175, 238, 238, 0.4)', // Pale turquoise - transparent\n 'rgba(224, 255, 255, 0.4)', // Light cyan - transparent\n];\n\nexport function createBubbleEffect(options: EffectOptions = {}): Effect {\n const {\n colors = DEFAULT_COLORS,\n particleCount = 1, // Spawn one bubble at a time\n gravity = -0.02, // Gentle upward buoyancy\n maxLife = 180, // Longer lifetime for slow rise\n velocity = 0.2, // Minimal base horizontal drift\n throttle = 150, // Spawn every 150ms - much less frequent\n minMoveDistance = 15, // Only spawn when cursor moves 15px\n } = options;\n\n return {\n throttle,\n minMoveDistance,\n onMouseMove(x: number, y: number): Particle[] {\n const particles: Particle[] = [];\n\n for (let i = 0; i < particleCount; i++) {\n const bubbleImage = ImageLoader.getRandomBubble();\n\n // Create more dramatic size variation (15-45 range for 2.5x multiplier = 37-112px actual)\n const baseSize = 15 + Math.random() * 30;\n\n particles.push(\n new Particle({\n x: x + (Math.random() - 0.5) * 10, // Spawn closer to pointer\n y: y + (Math.random() - 0.5) * 10,\n vx: (Math.random() - 0.5) * velocity,\n vy: -Math.random() * 0.15 - 0.1, // Very slow, consistent upward\n size: baseSize, // Wide size variation (15-45)\n color: randomColor(colors),\n maxLife: maxLife + Math.random() * 60,\n gravity,\n shape: 'bubble',\n wobbleAmplitude: 0.3, // Gentle horizontal wobble\n wobbleSpeed: 0.05, // Slow wobble oscillation\n image: bubbleImage || undefined, // Use image if loaded, fallback to canvas\n initialScale: 0.3, // Start at 30% size for pop-up effect\n scaleUpDuration: 15, // Grow to full size over 15 frames (~250ms)\n })\n );\n }\n\n return particles;\n },\n };\n}\n","import { useEffect, useRef, useMemo } from 'react';\nimport { CursorFXEngine, createFairyDustEffect, createSparkleEffect, createConfettiEffect, createRetroCRTEffect, createSnowEffect, createBubbleEffect, ImageLoader } from '../core';\n\nexport type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';\n\nexport interface UseCursorFXOptions {\n effect?: CursorEffectType;\n colors?: string[];\n particleCount?: number;\n particleSize?: number;\n gravity?: number;\n maxLife?: number;\n velocity?: number;\n enabled?: boolean;\n}\n\n/**\n * React hook for cursor effects.\n * Returns a ref to attach to your canvas element.\n *\n * @param options - Configuration options for the effect\n * @returns Canvas ref to attach to <canvas> element\n *\n * @example\n * ```tsx\n * function App() {\n * useCursorFX({\n * colors: ['#FFD700', '#FF69B4'],\n * particleCount: 5\n * });\n *\n * return <div>Your content</div>;\n * }\n * ```\n */\nexport function useCursorFX(options: UseCursorFXOptions = {}) {\n const {\n enabled = true,\n effect = 'fairyDust',\n colors,\n particleCount,\n particleSize,\n gravity,\n maxLife,\n velocity\n } = options;\n const engineRef = useRef<CursorFXEngine | null>(null);\n\n // Memoize colors array to prevent unnecessary re-renders when passed inline\n const memoizedColors = useMemo(() => colors, [colors ? JSON.stringify(colors) : undefined]);\n\n useEffect(() => {\n // SSR safety check\n if (typeof window === 'undefined') return;\n if (!enabled) return;\n\n // Check for prefers-reduced-motion\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) return;\n\n // Create engine (automatically creates canvas)\n const engine = new CursorFXEngine();\n\n // Build options object, only including user-provided values\n const effectOptions = {\n ...(memoizedColors && { colors: memoizedColors }),\n ...(particleCount !== undefined && { particleCount }),\n ...(particleSize !== undefined && { particleSize }),\n ...(gravity !== undefined && { gravity }),\n ...(maxLife !== undefined && { maxLife }),\n ...(velocity !== undefined && { velocity }),\n };\n\n // Select effect based on type\n const selectedEffect =\n effect === 'confetti'\n ? createConfettiEffect(effectOptions)\n : effect === 'sparkle'\n ? createSparkleEffect(effectOptions)\n : effect === 'retroCRT'\n ? createRetroCRTEffect(effectOptions)\n : effect === 'snow'\n ? createSnowEffect(effectOptions)\n : effect === 'bubble'\n ? createBubbleEffect(effectOptions)\n : createFairyDustEffect(effectOptions);\n\n // Start the effect\n engine.start(selectedEffect);\n engineRef.current = engine;\n\n // Cleanup on unmount\n return () => {\n engine.destroy();\n engineRef.current = null;\n };\n }, [enabled, effect, memoizedColors, particleCount, particleSize, gravity, maxLife, velocity]);\n\n return engineRef.current;\n}\n\n/**\n * CursorFX component for React.\n * Simple wrapper over useCursorFX hook.\n *\n * @param props - Configuration options for the effect\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <>\n * <CursorFX\n * colors={['#FFD700', '#FF69B4']}\n * particleCount={5}\n * />\n * <YourContent />\n * </>\n * );\n * }\n * ```\n */\nexport function CursorFX(props: UseCursorFXOptions) {\n useCursorFX(props);\n return null;\n}\n\n// Export types for TypeScript users\nexport type { EffectOptions } from '../core/types';\n\n// Export ImageLoader for preloading bubble and snowflake images\nexport { ImageLoader };\n"]}
|
package/dist/react/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CursorFXEngine, createConfettiEffect, createSparkleEffect, createRetroCRTEffect, createSnowEffect, createBubbleEffect, createFairyDustEffect } from '../chunk-5ZV2U5LA.mjs';
|
|
2
|
+
export { ImageLoader } from '../chunk-5ZV2U5LA.mjs';
|
|
2
3
|
import { useRef, useMemo, useEffect } from 'react';
|
|
3
4
|
|
|
4
5
|
function useCursorFX(options = {}) {
|
|
@@ -20,9 +21,7 @@ function useCursorFX(options = {}) {
|
|
|
20
21
|
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
21
22
|
if (prefersReducedMotion) return;
|
|
22
23
|
const engine = new CursorFXEngine();
|
|
23
|
-
const
|
|
24
|
-
particleCount: 2,
|
|
25
|
-
// Reduced from default 3
|
|
24
|
+
const effectOptions = {
|
|
26
25
|
...memoizedColors && { colors: memoizedColors },
|
|
27
26
|
...particleCount !== void 0 && { particleCount },
|
|
28
27
|
...particleSize !== void 0 && { particleSize },
|
|
@@ -30,7 +29,7 @@ function useCursorFX(options = {}) {
|
|
|
30
29
|
...maxLife !== void 0 && { maxLife },
|
|
31
30
|
...velocity !== void 0 && { velocity }
|
|
32
31
|
};
|
|
33
|
-
const selectedEffect = effect === "confetti" ? createConfettiEffect(
|
|
32
|
+
const selectedEffect = effect === "confetti" ? createConfettiEffect(effectOptions) : effect === "sparkle" ? createSparkleEffect(effectOptions) : effect === "retroCRT" ? createRetroCRTEffect(effectOptions) : effect === "snow" ? createSnowEffect(effectOptions) : effect === "bubble" ? createBubbleEffect(effectOptions) : createFairyDustEffect(effectOptions);
|
|
34
33
|
engine.start(selectedEffect);
|
|
35
34
|
engineRef.current = engine;
|
|
36
35
|
return () => {
|
package/dist/react/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/react/index.tsx"],"names":[],"mappings":";;;;AAmCO,SAAS,WAAA,CAAY,OAAA,GAA8B,EAAC,EAAG;AAC5D,EAAA,MAAM;AAAA,IACJ,OAAA,GAAU,IAAA;AAAA,IACV,MAAA,GAAS,WAAA;AAAA,IACT,MAAA;AAAA,IACA,aAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACF,GAAI,OAAA;AACJ,EAAA,MAAM,SAAA,GAAY,OAA8B,IAAI,CAAA;AAGpD,EAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,MAAM,MAAA,EAAQ,CAAC,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA,GAAI,MAAS,CAAC,CAAA;AAE1F,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,IAAA,IAAI,CAAC,OAAA,EAAS;AAGd,IAAA,MAAM,oBAAA,GAAuB,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA,CAAE,OAAA;AACnF,IAAA,IAAI,oBAAA,EAAsB;AAG1B,IAAA,MAAM,MAAA,GAAS,IAAI,cAAA,EAAe;AAGlC,IAAA,MAAM,aAAA,GAAgB;AAAA,MACpB,GAAI,cAAA,IAAkB,EAAE,MAAA,EAAQ,cAAA,EAAe;AAAA,MAC/C,GAAI,aAAA,KAAkB,MAAA,IAAa,EAAE,aAAA,EAAc;AAAA,MACnD,GAAI,YAAA,KAAiB,MAAA,IAAa,EAAE,YAAA,EAAa;AAAA,MACjD,GAAI,OAAA,KAAY,MAAA,IAAa,EAAE,OAAA,EAAQ;AAAA,MACvC,GAAI,OAAA,KAAY,MAAA,IAAa,EAAE,OAAA,EAAQ;AAAA,MACvC,GAAI,QAAA,KAAa,MAAA,IAAa,EAAE,QAAA;AAAS,KAC3C;AAGA,IAAA,MAAM,cAAA,GACJ,MAAA,KAAW,UAAA,GACP,oBAAA,CAAqB,aAAa,CAAA,GAClC,MAAA,KAAW,SAAA,GACX,mBAAA,CAAoB,aAAa,CAAA,GACjC,MAAA,KAAW,UAAA,GACX,oBAAA,CAAqB,aAAa,CAAA,GAClC,MAAA,KAAW,MAAA,GACX,gBAAA,CAAiB,aAAa,CAAA,GAC9B,MAAA,KAAW,QAAA,GACX,kBAAA,CAAmB,aAAa,CAAA,GAChC,qBAAA,CAAsB,aAAa,CAAA;AAGzC,IAAA,MAAA,CAAO,MAAM,cAAc,CAAA;AAC3B,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAGpB,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,OAAA,EAAQ;AACf,MAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,IACtB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,MAAA,EAAQ,cAAA,EAAgB,eAAe,YAAA,EAAc,OAAA,EAAS,OAAA,EAAS,QAAQ,CAAC,CAAA;AAE7F,EAAA,OAAO,SAAA,CAAU,OAAA;AACnB;AAuBO,SAAS,SAAS,KAAA,EAA2B;AAClD,EAAA,WAAA,CAAY,KAAK,CAAA;AACjB,EAAA,OAAO,IAAA;AACT","file":"index.mjs","sourcesContent":["import { useEffect, useRef, useMemo } from 'react';\nimport { CursorFXEngine, createFairyDustEffect, createSparkleEffect, createConfettiEffect, createRetroCRTEffect, createSnowEffect, createBubbleEffect, ImageLoader } from '../core';\n\nexport type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';\n\nexport interface UseCursorFXOptions {\n effect?: CursorEffectType;\n colors?: string[];\n particleCount?: number;\n particleSize?: number;\n gravity?: number;\n maxLife?: number;\n velocity?: number;\n enabled?: boolean;\n}\n\n/**\n * React hook for cursor effects.\n * Returns a ref to attach to your canvas element.\n *\n * @param options - Configuration options for the effect\n * @returns Canvas ref to attach to <canvas> element\n *\n * @example\n * ```tsx\n * function App() {\n * useCursorFX({\n * colors: ['#FFD700', '#FF69B4'],\n * particleCount: 5\n * });\n *\n * return <div>Your content</div>;\n * }\n * ```\n */\nexport function useCursorFX(options: UseCursorFXOptions = {}) {\n const {\n enabled = true,\n effect = 'fairyDust',\n colors,\n particleCount,\n particleSize,\n gravity,\n maxLife,\n velocity\n } = options;\n const engineRef = useRef<CursorFXEngine | null>(null);\n\n // Memoize colors array to prevent unnecessary re-renders when passed inline\n const memoizedColors = useMemo(() => colors, [colors ? JSON.stringify(colors) : undefined]);\n\n useEffect(() => {\n // SSR safety check\n if (typeof window === 'undefined') return;\n if (!enabled) return;\n\n // Check for prefers-reduced-motion\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) return;\n\n // Create engine (automatically creates canvas)\n const engine = new CursorFXEngine();\n\n // Build options object, only including user-provided values\n const effectOptions = {\n ...(memoizedColors && { colors: memoizedColors }),\n ...(particleCount !== undefined && { particleCount }),\n ...(particleSize !== undefined && { particleSize }),\n ...(gravity !== undefined && { gravity }),\n ...(maxLife !== undefined && { maxLife }),\n ...(velocity !== undefined && { velocity }),\n };\n\n // Select effect based on type\n const selectedEffect =\n effect === 'confetti'\n ? createConfettiEffect(effectOptions)\n : effect === 'sparkle'\n ? createSparkleEffect(effectOptions)\n : effect === 'retroCRT'\n ? createRetroCRTEffect(effectOptions)\n : effect === 'snow'\n ? createSnowEffect(effectOptions)\n : effect === 'bubble'\n ? createBubbleEffect(effectOptions)\n : createFairyDustEffect(effectOptions);\n\n // Start the effect\n engine.start(selectedEffect);\n engineRef.current = engine;\n\n // Cleanup on unmount\n return () => {\n engine.destroy();\n engineRef.current = null;\n };\n }, [enabled, effect, memoizedColors, particleCount, particleSize, gravity, maxLife, velocity]);\n\n return engineRef.current;\n}\n\n/**\n * CursorFX component for React.\n * Simple wrapper over useCursorFX hook.\n *\n * @param props - Configuration options for the effect\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <>\n * <CursorFX\n * colors={['#FFD700', '#FF69B4']}\n * particleCount={5}\n * />\n * <YourContent />\n * </>\n * );\n * }\n * ```\n */\nexport function CursorFX(props: UseCursorFXOptions) {\n useCursorFX(props);\n return null;\n}\n\n// Export types for TypeScript users\nexport type { EffectOptions } from '../core/types';\n\n// Export ImageLoader for preloading bubble and snowflake images\nexport { ImageLoader };\n"]}
|
package/dist/vanilla/index.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
export { E as EffectOptions } from '../
|
|
2
|
-
export { I as ImageLoader } from '../imageLoader-Bgr5GJIX.mjs';
|
|
1
|
+
export { E as EffectOptions, I as ImageLoader } from '../imageLoader-VUu0PjNk.mjs';
|
|
3
2
|
|
|
4
3
|
type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';
|
|
5
4
|
interface InitCursorFXOptions {
|
package/dist/vanilla/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
export { E as EffectOptions } from '../
|
|
2
|
-
export { I as ImageLoader } from '../imageLoader-Bgr5GJIX.js';
|
|
1
|
+
export { E as EffectOptions, I as ImageLoader } from '../imageLoader-VUu0PjNk.js';
|
|
3
2
|
|
|
4
3
|
type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';
|
|
5
4
|
interface InitCursorFXOptions {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cursor-fx",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Beautiful, customizable cursor effects for React and vanilla JavaScript. Add magical fairy dust particles that follow your cursor with minimal setup.",
|
|
5
5
|
"author": "Anto Pravin C <antopravin.dev@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/antopravin-dev/cursor-fx.git"
|
|
10
10
|
},
|
|
11
|
-
"homepage": "https://
|
|
11
|
+
"homepage": "https://www.antoprav.in/work/cursor-fx",
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/antopravin-dev/cursor-fx/issues"
|
|
14
14
|
},
|
|
@@ -87,4 +87,4 @@
|
|
|
87
87
|
"engines": {
|
|
88
88
|
"node": ">=16.0.0"
|
|
89
89
|
}
|
|
90
|
-
}
|
|
90
|
+
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
declare class ImageLoader {
|
|
2
|
-
private static images;
|
|
3
|
-
private static loading;
|
|
4
|
-
static loadImage(src: string): Promise<HTMLImageElement>;
|
|
5
|
-
static loadBubbles(basePath?: string): Promise<HTMLImageElement[]>;
|
|
6
|
-
static loadSnowflakes(basePath?: string): Promise<HTMLImageElement[]>;
|
|
7
|
-
static getRandomBubble(): HTMLImageElement | null;
|
|
8
|
-
static getRandomSnowflake(): HTMLImageElement | null;
|
|
9
|
-
static isLoaded(): boolean;
|
|
10
|
-
static clear(): void;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export { ImageLoader as I };
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
declare class ImageLoader {
|
|
2
|
-
private static images;
|
|
3
|
-
private static loading;
|
|
4
|
-
static loadImage(src: string): Promise<HTMLImageElement>;
|
|
5
|
-
static loadBubbles(basePath?: string): Promise<HTMLImageElement[]>;
|
|
6
|
-
static loadSnowflakes(basePath?: string): Promise<HTMLImageElement[]>;
|
|
7
|
-
static getRandomBubble(): HTMLImageElement | null;
|
|
8
|
-
static getRandomSnowflake(): HTMLImageElement | null;
|
|
9
|
-
static isLoaded(): boolean;
|
|
10
|
-
static clear(): void;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export { ImageLoader as I };
|