{"version":3,"file":"components\\ui\\scratcher.cjs","sources":["webpack://@arolariu/components/./src/components/ui/scratcher.tsx"],"sourcesContent":["\n\nimport { cn } from \"@/lib/utils\";\nimport { motion, useAnimation } from \"motion/react\";\nimport React, { useEffect, useRef, useState } from \"react\";\n\ninterface ScratcherProps {\n  children: React.ReactNode;\n  width: number;\n  height: number;\n  minScratchPercentage?: number;\n  className?: string;\n  onComplete?: () => void;\n  gradientColors?: [string, string, string];\n}\n\nexport const Scratcher: React.FC<ScratcherProps> = ({\n  width,\n  height,\n  minScratchPercentage = 50,\n  onComplete,\n  children,\n  className,\n  gradientColors = [\"#A97CF8\", \"#F38CB8\", \"#FDCC92\"],\n}) => {\n  const canvasRef = useRef<HTMLCanvasElement>(null);\n  const [isScratching, setIsScratching] = useState(false);\n  const [isComplete, setIsComplete] = useState(false);\n\n  const controls = useAnimation();\n\n  useEffect(() => {\n    const canvas = canvasRef.current;\n    const ctx = canvas?.getContext(\"2d\");\n    if (canvas && ctx) {\n      ctx.fillStyle = \"#ccc\";\n      ctx.fillRect(0, 0, canvas.width, canvas.height);\n      const gradient = ctx.createLinearGradient(\n        0,\n        0,\n        canvas.width,\n        canvas.height\n      );\n      gradient.addColorStop(0, gradientColors[0]);\n      gradient.addColorStop(0.5, gradientColors[1]);\n      gradient.addColorStop(1, gradientColors[2]);\n      ctx.fillStyle = gradient;\n      ctx.fillRect(0, 0, canvas.width, canvas.height);\n    }\n  }, [gradientColors]);\n\n  useEffect(() => {\n    const handleDocumentMouseMove = (event: MouseEvent) => {\n      if (!isScratching) return;\n      scratch(event.clientX, event.clientY);\n    };\n\n    const handleDocumentTouchMove = (event: TouchEvent) => {\n      if (!isScratching) return;\n      const touch = event.touches[0];\n      scratch(touch.clientX, touch.clientY);\n    };\n\n    const handleDocumentMouseUp = () => {\n      setIsScratching(false);\n      checkCompletion();\n    };\n\n    const handleDocumentTouchEnd = () => {\n      setIsScratching(false);\n      checkCompletion();\n    };\n\n    document.addEventListener(\"mousedown\", handleDocumentMouseMove);\n    document.addEventListener(\"mousemove\", handleDocumentMouseMove);\n    document.addEventListener(\"touchstart\", handleDocumentTouchMove);\n    document.addEventListener(\"touchmove\", handleDocumentTouchMove);\n    document.addEventListener(\"mouseup\", handleDocumentMouseUp);\n    document.addEventListener(\"touchend\", handleDocumentTouchEnd);\n    document.addEventListener(\"touchcancel\", handleDocumentTouchEnd);\n\n    return () => {\n      document.removeEventListener(\"mousedown\", handleDocumentMouseMove);\n      document.removeEventListener(\"mousemove\", handleDocumentMouseMove);\n      document.removeEventListener(\"touchstart\", handleDocumentTouchMove);\n      document.removeEventListener(\"touchmove\", handleDocumentTouchMove);\n      document.removeEventListener(\"mouseup\", handleDocumentMouseUp);\n      document.removeEventListener(\"touchend\", handleDocumentTouchEnd);\n      document.removeEventListener(\"touchcancel\", handleDocumentTouchEnd);\n    };\n  }, [isScratching]);\n\n  const handleMouseDown = () => setIsScratching(true);\n\n  const handleTouchStart = () => setIsScratching(true);\n\n  const scratch = (clientX: number, clientY: number) => {\n    const canvas = canvasRef.current;\n    const ctx = canvas?.getContext(\"2d\");\n    if (canvas && ctx) {\n      const rect = canvas.getBoundingClientRect();\n      const x = clientX - rect.left + 16;\n      const y = clientY - rect.top + 16;\n      ctx.globalCompositeOperation = \"destination-out\";\n      ctx.beginPath();\n      ctx.arc(x, y, 30, 0, Math.PI * 2);\n      ctx.fill();\n    }\n  };\n\n  const startAnimation = async () => {\n    await controls.start({\n      scale: [1, 1.5, 1],\n      rotate: [0, 10, -10, 10, -10, 0],\n      transition: { duration: 0.5 },\n    });\n\n    // Call onComplete after animation finishes\n    if (onComplete) {\n      onComplete();\n    }\n  };\n\n  const checkCompletion = () => {\n    if (isComplete) return;\n\n    const canvas = canvasRef.current;\n    const ctx = canvas?.getContext(\"2d\");\n    if (canvas && ctx) {\n      const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n      const pixels = imageData.data;\n      const totalPixels = pixels.length / 4;\n      let clearPixels = 0;\n\n      for (let i = 3; i < pixels.length; i += 4) {\n        if (pixels[i] === 0) clearPixels++;\n      }\n\n      const percentage = (clearPixels / totalPixels) * 100;\n\n      if (percentage >= minScratchPercentage) {\n        setIsComplete(true);\n        ctx.clearRect(0, 0, canvas.width, canvas.height);\n        startAnimation();\n      }\n    }\n  };\n\n  return (\n    <motion.div\n      className={cn(\"relative select-none\", className)}\n      style={{\n        width,\n        height,\n        cursor:\n          \"url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDMyIDMyIj4KICA8Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIxNSIgc3R5bGU9ImZpbGw6I2ZmZjtzdHJva2U6IzAwMDtzdHJva2Utd2lkdGg6MXB4OyIgLz4KPC9zdmc+'), auto\",\n      }}\n      animate={controls}\n    >\n      <canvas\n        ref={canvasRef}\n        width={width}\n        height={height}\n        className=\"absolute left-0 top-0\"\n        onMouseDown={handleMouseDown}\n        onTouchStart={handleTouchStart}\n      ></canvas>\n      {children}\n    </motion.div>\n  );\n};\n"],"names":["Scratcher","width","height","minScratchPercentage","onComplete","children","className","gradientColors","canvasRef","useRef","isScratching","setIsScratching","useState","isComplete","setIsComplete","controls","useAnimation","useEffect","canvas","ctx","gradient","handleDocumentMouseMove","event","scratch","handleDocumentTouchMove","touch","handleDocumentMouseUp","checkCompletion","handleDocumentTouchEnd","document","handleMouseDown","handleTouchStart","clientX","clientY","rect","x","y","Math","startAnimation","imageData","pixels","totalPixels","clearPixels","i","percentage","motion","cn"],"mappings":"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"}