cursor-fx 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,4 +1,4 @@
1
- export { E as EffectOptions } from '../particle-CimoPApW.mjs';
1
+ export { E as EffectOptions, I as ImageLoader } from '../imageLoader-VUu0PjNk.mjs';
2
2
 
3
3
  type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';
4
4
  interface InitCursorFXOptions {
@@ -1,4 +1,4 @@
1
- export { E as EffectOptions } from '../particle-CimoPApW.js';
1
+ export { E as EffectOptions, I as ImageLoader } from '../imageLoader-VUu0PjNk.js';
2
2
 
3
3
  type CursorEffectType = 'fairyDust' | 'sparkle' | 'confetti' | 'retroCRT' | 'snow' | 'bubble';
4
4
  interface InitCursorFXOptions {
@@ -760,18 +760,14 @@ function initCursorFX(options = {}) {
760
760
  }
761
761
  const engine = new CursorFXEngine();
762
762
  const { effect = "fairyDust", ...effectOptions } = options;
763
- const optimizedOptions = {
764
- particleCount: 2,
765
- // Reduced from default 3
766
- ...effectOptions
767
- };
768
- const selectedEffect = effect === "confetti" ? createConfettiEffect(optimizedOptions) : effect === "sparkle" ? createSparkleEffect(optimizedOptions) : effect === "retroCRT" ? createRetroCRTEffect(optimizedOptions) : effect === "snow" ? createSnowEffect(optimizedOptions) : effect === "bubble" ? createBubbleEffect(optimizedOptions) : createFairyDustEffect(optimizedOptions);
763
+ const selectedEffect = effect === "confetti" ? createConfettiEffect(effectOptions) : effect === "sparkle" ? createSparkleEffect(effectOptions) : effect === "retroCRT" ? createRetroCRTEffect(effectOptions) : effect === "snow" ? createSnowEffect(effectOptions) : effect === "bubble" ? createBubbleEffect(effectOptions) : createFairyDustEffect(effectOptions);
769
764
  engine.start(selectedEffect);
770
765
  return {
771
766
  destroy: () => engine.destroy()
772
767
  };
773
768
  }
774
769
 
770
+ exports.ImageLoader = ImageLoader;
775
771
  exports.initCursorFX = initCursorFX;
776
772
  //# sourceMappingURL=index.js.map
777
773
  //# sourceMappingURL=index.js.map