import React, { useState, useRef, useEffect } from 'react'; import { Palette, Download, RotateCcw, Upload, Eraser } from 'lucide-react'; const ColoringBook = () => { const colors = [ '#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8', '#F7DC6F', '#BB8FCE', '#85C1E2', '#F8B739', '#52C41A', '#eb2f96', '#722ED1', '#13C2C2', '#FA8C16', '#A0D911', '#000000', '#FFFFFF', '#8B4513', '#FFB6C1', '#E6E6FA' ]; const INITIAL_IMAGE_URL = 'https://cdn.prod.website-files.com/68424a45023d688185720fd0/691b63550cb50145841779c1_Vivun-ColouringBook-AvaVsTeamate-1025-v1-PRINT-Flat.pdf.svg'; const [selectedColor, setSelectedColor] = useState(colors[0]); const [brushSize, setBrushSize] = useState(20); const [isEraser, setIsEraser] = useState(false); const [isDrawing, setIsDrawing] = useState(false); const [isLoading, setIsLoading] = useState(true); const canvasRef = useRef(null); const [imageLoaded, setImageLoaded] = useState(false); useEffect(() => { const canvas = canvasRef.current; if (!canvas) return; const ctx = canvas.getContext('2d'); const img = new Image(); img.crossOrigin = 'anonymous'; img.onload = () => { canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); setImageLoaded(true); setIsLoading(false); }; img.onerror = () => { // If direct loading fails, try a different approach setIsLoading(false); alert('Unable to load the image directly. This is likely due to browser security restrictions (CORS). Please download the SVG from the URL and use the Upload button to add it.'); }; img.src = INITIAL_IMAGE_URL; }, []); const startDrawing = (e) => { setIsDrawing(true); draw(e); }; const stopDrawing = () => { setIsDrawing(false); }; const draw = (e) => { if (!isDrawing && e.type !== 'mousedown' && e.type !== 'click') return; const canvas = canvasRef.current; const rect = canvas.getBoundingClientRect(); const scaleX = canvas.width / rect.width; const scaleY = canvas.height / rect.height; const x = (e.clientX - rect.left) * scaleX; const y = (e.clientY - rect.top) * scaleY; const ctx = canvas.getContext('2d'); ctx.fillStyle = isEraser ? '#FFFFFF' : selectedColor; ctx.beginPath(); ctx.arc(x, y, brushSize, 0, Math.PI * 2); ctx.fill(); }; const handleTouchStart = (e) => { e.preventDefault(); setIsDrawing(true); const touch = e.touches[0]; const mouseEvent = new MouseEvent('mousedown', { clientX: touch.clientX, clientY: touch.clientY }); draw(mouseEvent); }; const handleTouchMove = (e) => { e.preventDefault(); if (!isDrawing) return; const touch = e.touches[0]; const mouseEvent = new MouseEvent('mousemove', { clientX: touch.clientX, clientY: touch.clientY }); draw(mouseEvent); }; const handleTouchEnd = (e) => { e.preventDefault(); setIsDrawing(false); }; const resetCanvas = () => { const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); const img = new Image(); img.crossOrigin = 'anonymous'; img.onload = () => { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0); }; img.src = INITIAL_IMAGE_URL; }; const handleImageUpload = (e) => { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = (event) => { const img = new Image(); img.onload = () => { const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); setImageLoaded(true); setIsLoading(false); }; img.src = event.target.result; }; reader.readAsDataURL(file); } }; const downloadImage = () => { const canvas = canvasRef.current; const link = document.createElement('a'); link.download = 'my-coloring-page.png'; link.href = canvas.toDataURL(); link.click(); }; if (isLoading) { return (
🎨
Loading your coloring book...
); } if (!imageLoaded) { return (
📁

Upload Your Coloring Page

Due to browser security, we couldn't load the image automatically. Please download the SVG file and upload it here.

Download SVG File
); } return (

🎨 Digital Coloring Book

Click or drag to paint! Use the eraser to fix mistakes.

{/* Controls */}
setBrushSize(Number(e.target.value))} className="w-32" /> {brushSize}px
{/* Color Palette */}

Choose a Color

{colors.map((color) => (
{/* Canvas */}
{/* Action Buttons */}
); }; export default ColoringBook;