{"version":3,"file":"ngwr-confetti.mjs","sources":["../../../projects/lib/confetti/wr-confetti.ts","../../../projects/lib/confetti/ngwr-confetti.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { DOCUMENT } from '@angular/common';\nimport { Service, inject } from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\n\nimport type { WrConfettiOptions } from './interfaces';\n\nconst DEFAULTS: Required<WrConfettiOptions> = {\n  count: 80,\n  spread: 60,\n  angle: 90,\n  velocity: 12,\n  gravity: 0.35,\n  drag: 0.92,\n  origin: { x: 0.5, y: 1 },\n  colors: ['#3969e2', '#f51c6a', '#00a400', '#ffba00', '#fa383e'],\n  size: 8,\n  ttl: 180,\n};\n\ninterface Particle {\n  x: number;\n  y: number;\n  vx: number;\n  vy: number;\n  rotation: number;\n  rotationSpeed: number;\n  color: string;\n  size: number;\n  ttl: number;\n}\n\n/**\n * Burst of celebratory confetti particles painted onto a single shared\n * full-viewport canvas. The canvas is created on first call and reused.\n *\n * @example\n * ```ts\n * const confetti = inject(WrConfetti);\n * confetti.fire();\n * confetti.fire({ count: 200, origin: { x: 0.25, y: 0.5 } });\n * ```\n *\n * @see https://ngwr.dev/animations/confetti\n */\n@Service()\nexport class WrConfetti {\n  private readonly doc = inject(DOCUMENT);\n  private readonly platform = inject(WrPlatform);\n\n  private canvas: HTMLCanvasElement | null = null;\n  private ctx: CanvasRenderingContext2D | null = null;\n  private particles: Particle[] = [];\n  private rafId: number | null = null;\n\n  /** Spawn a confetti burst with the given (or default) options. */\n  fire(options: WrConfettiOptions = {}): void {\n    if (!this.platform.isBrowser) return;\n    if (this.platform.prefersReducedMotion()) return;\n    const opts: Required<WrConfettiOptions> = { ...DEFAULTS, ...options };\n    this.ensureCanvas();\n    this.spawn(opts);\n    this.rafId ??= requestAnimationFrame(() => this.tick());\n  }\n\n  // Internals\n\n  private ensureCanvas(): void {\n    if (this.canvas) return;\n    const win = this.doc.defaultView;\n    if (!win) return;\n    const canvas = this.doc.createElement('canvas');\n    canvas.style.position = 'fixed';\n    canvas.style.inset = '0';\n    canvas.style.width = '100%';\n    canvas.style.height = '100%';\n    canvas.style.pointerEvents = 'none';\n    canvas.style.zIndex = '9999';\n    canvas.setAttribute('aria-hidden', 'true');\n    this.doc.body.appendChild(canvas);\n    this.canvas = canvas;\n    this.ctx = canvas.getContext('2d');\n    this.resize();\n    win.addEventListener('resize', () => this.resize());\n  }\n\n  private resize(): void {\n    if (!this.canvas) return;\n    const win = this.doc.defaultView;\n    if (!win) return;\n    const dpr = win.devicePixelRatio || 1;\n    this.canvas.width = win.innerWidth * dpr;\n    this.canvas.height = win.innerHeight * dpr;\n    this.ctx?.setTransform(dpr, 0, 0, dpr, 0, 0);\n  }\n\n  private spawn(opts: Required<WrConfettiOptions>): void {\n    const win = this.doc.defaultView;\n    if (!win) return;\n    const cx = opts.origin.x * win.innerWidth;\n    const cy = opts.origin.y * win.innerHeight;\n    const halfSpread = (opts.spread / 2) * (Math.PI / 180);\n    for (let i = 0; i < opts.count; i++) {\n      // Launch direction: 90° = up (default), 0° = right — same convention\n      // as canvas-confetti. Jitter spreads the cone around it.\n      const base = (-opts.angle * Math.PI) / 180;\n      const angle = base + (Math.random() - 0.5) * 2 * halfSpread;\n      const speed = opts.velocity * (0.6 + Math.random() * 0.8);\n      this.particles.push({\n        x: cx,\n        y: cy,\n        vx: Math.cos(angle) * speed,\n        vy: Math.sin(angle) * speed,\n        rotation: Math.random() * Math.PI * 2,\n        rotationSpeed: (Math.random() - 0.5) * 0.3,\n        color: opts.colors[Math.floor(Math.random() * opts.colors.length)],\n        size: opts.size * (0.8 + Math.random() * 0.6),\n        ttl: opts.ttl,\n      });\n    }\n  }\n\n  private tick(): void {\n    const ctx = this.ctx;\n    const win = this.doc.defaultView;\n    if (!ctx || !win) {\n      this.rafId = null;\n      return;\n    }\n    ctx.clearRect(0, 0, win.innerWidth, win.innerHeight);\n    const next: Particle[] = [];\n    for (const p of this.particles) {\n      p.vx *= DEFAULTS.drag;\n      p.vy = p.vy * DEFAULTS.drag + DEFAULTS.gravity;\n      p.x += p.vx;\n      p.y += p.vy;\n      p.rotation += p.rotationSpeed;\n      p.ttl -= 1;\n      if (p.ttl <= 0 || p.y > win.innerHeight + 50) continue;\n      next.push(p);\n      ctx.save();\n      ctx.translate(p.x, p.y);\n      ctx.rotate(p.rotation);\n      ctx.globalAlpha = Math.min(1, p.ttl / 60);\n      ctx.fillStyle = p.color;\n      ctx.fillRect(-p.size / 2, -p.size / 2, p.size, p.size * 0.6);\n      ctx.restore();\n    }\n    this.particles = next;\n    if (this.particles.length > 0) {\n      this.rafId = requestAnimationFrame(() => this.tick());\n    } else {\n      this.rafId = null;\n    }\n  }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}