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 CHANGED
@@ -6,7 +6,7 @@ Beautiful, customizable cursor particle effects for React and vanilla JavaScript
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
7
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
8
8
 
9
- **[🎮 Live Demo](https://antopravin-dev.github.io/cursor-fx)** | **[📖 Documentation](#-api-reference)** | **[⭐ GitHub](https://github.com/antopravin-dev/cursor-fx)**
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
- Some effects support PNG assets for photorealistic quality:
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
- // Preload before using effects
315
- await ImageLoader.loadBubbles('/path/to/bubbles');
316
- await ImageLoader.loadSnowflakes('/path/to/snowflakes');
391
+ ### ImageLoader API
317
392
 
318
- // Effects will automatically use images if loaded
319
- const bubbleEffect = createBubbleEffect();
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
- - 3 snowflake variations (~140KB total)
419
+ - 2 snowflake variations (~140KB total)
325
420
 
326
- Assets are automatically copied to `dist/bubbles/` and `dist/snowflakes/` during build.
421
+ Assets are bundled at `dist/bubbles/` and `dist/snowflakes/`.
327
422
 
328
423
  ## 🎨 Customizing Colors
329
424
 
@@ -1,7 +1,6 @@
1
- export { C as CursorFXEngine } from '../engine-DtYS3_cn.mjs';
2
- import { E as EffectOptions, a as Effect } from '../particle-CimoPApW.mjs';
3
- export { d as EffectFunction, c as EngineOptions, P as Particle, b as ParticleConfig } from '../particle-CimoPApW.mjs';
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;
@@ -1,7 +1,6 @@
1
- export { C as CursorFXEngine } from '../engine-BiVjsHvN.js';
2
- import { E as EffectOptions, a as Effect } from '../particle-CimoPApW.js';
3
- export { d as EffectFunction, c as EngineOptions, P as Particle, b as ParticleConfig } from '../particle-CimoPApW.js';
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;
@@ -1,4 +1,4 @@
1
- import { c as EngineOptions, P as Particle, a as Effect } from './particle-CimoPApW.mjs';
1
+ import { c as EngineOptions, P as Particle, a as Effect } from './imageLoader-VUu0PjNk.mjs';
2
2
 
3
3
  declare class CursorFXEngine {
4
4
  private canvas;
@@ -1,4 +1,4 @@
1
- import { c as EngineOptions, P as Particle, a as Effect } from './particle-CimoPApW.js';
1
+ import { c as EngineOptions, P as Particle, a as Effect } from './imageLoader-VUu0PjNk.js';
2
2
 
3
3
  declare class CursorFXEngine {
4
4
  private canvas;
@@ -66,4 +66,16 @@ declare class Particle {
66
66
  draw(ctx: CanvasRenderingContext2D): void;
67
67
  }
68
68
 
69
- export { type EffectOptions as E, Particle as P, type Effect as a, type ParticleConfig as b, type EngineOptions as c, type EffectFunction as d };
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
- export { type EffectOptions as E, Particle as P, type Effect as a, type ParticleConfig as b, type EngineOptions as c, type EffectFunction as d };
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 };
@@ -1,5 +1,5 @@
1
- import { C as CursorFXEngine } from '../engine-DtYS3_cn.mjs';
2
- export { E as EffectOptions } from '../particle-CimoPApW.mjs';
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 {
@@ -1,5 +1,5 @@
1
- import { C as CursorFXEngine } from '../engine-BiVjsHvN.js';
2
- export { E as EffectOptions } from '../particle-CimoPApW.js';
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 {
@@ -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 optimizedOptions = {
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(optimizedOptions) : effect === "sparkle" ? createSparkleEffect(optimizedOptions) : effect === "retroCRT" ? createRetroCRTEffect(optimizedOptions) : effect === "snow" ? createSnowEffect(optimizedOptions) : effect === "bubble" ? createBubbleEffect(optimizedOptions) : createFairyDustEffect(optimizedOptions);
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
@@ -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"]}
@@ -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 optimizedOptions = {
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(optimizedOptions) : effect === "sparkle" ? createSparkleEffect(optimizedOptions) : effect === "retroCRT" ? createRetroCRTEffect(optimizedOptions) : effect === "snow" ? createSnowEffect(optimizedOptions) : effect === "bubble" ? createBubbleEffect(optimizedOptions) : createFairyDustEffect(optimizedOptions);
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 () => {
@@ -1 +1 @@
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,gBAAA,GAAmB;AAAA,MACvB,aAAA,EAAe,CAAA;AAAA;AAAA,MACf,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,gBAAgB,CAAA,GACrC,MAAA,KAAW,SAAA,GACX,mBAAA,CAAoB,gBAAgB,CAAA,GACpC,MAAA,KAAW,UAAA,GACX,oBAAA,CAAqB,gBAAgB,CAAA,GACrC,MAAA,KAAW,MAAA,GACX,gBAAA,CAAiB,gBAAgB,CAAA,GACjC,MAAA,KAAW,QAAA,GACX,kBAAA,CAAmB,gBAAgB,CAAA,GACnC,qBAAA,CAAsB,gBAAgB,CAAA;AAG5C,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 } 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/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"]}
@@ -1,5 +1,4 @@
1
- export { E as EffectOptions } from '../particle-CimoPApW.mjs';
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 {
@@ -1,5 +1,4 @@
1
- export { E as EffectOptions } from '../particle-CimoPApW.js';
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.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://antopravin-dev.github.io/cursor-fx",
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 };