import React, { useState, useRef, useEffect } from 'react'; import { Plus, Book, Calendar, MapPin, Edit, Palette, Download, Share, ChevronLeft, ChevronRight, Camera, Type, Brush, Eraser, RotateCcw } from 'lucide-react'; const TravelDrawingDiary = () => { const [currentView, setCurrentView] = useState('home'); // home, create-book, daily-entry, review-book, overview const [trips, setTrips] = useState([]); const [currentTrip, setCurrentTrip] = useState(null); const [currentDay, setCurrentDay] = useState(null); const [reviewPage, setReviewPage] = useState(0); // Drawing states const canvasRef = useRef(null); const [isDrawing, setIsDrawing] = useState(false); const [brushSize, setBrushSize] = useState(3); const [currentColor, setCurrentColor] = useState('#2D3436'); const [showColorPicker, setShowColorPicker] = useState(false); const [currentTool, setCurrentTool] = useState('brush'); // Form states const [tripForm, setTripForm] = useState({ title: '', cover: '', startDate: '', endDate: '' }); const [dayForm, setDayForm] = useState({ description: '', images: [] }); // Initialize canvas useEffect(() => { if (canvasRef.current && currentView === 'daily-entry') { const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); // Set canvas size for mobile const rect = canvas.getBoundingClientRect(); canvas.width = rect.width * window.devicePixelRatio; canvas.height = rect.height * window.devicePixelRatio; ctx.scale(window.devicePixelRatio, window.devicePixelRatio); ctx.lineCap = 'round'; ctx.lineJoin = 'round'; // Textured paper background ctx.fillStyle = '#FEFEFE'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Add subtle paper texture ctx.globalAlpha = 0.05; for (let i = 0; i < 50; i++) { ctx.fillStyle = Math.random() > 0.5 ? '#E8E8E8' : '#F5F5F5'; ctx.fillRect(Math.random() * canvas.width, Math.random() * canvas.height, 2, 2); } ctx.globalAlpha = 1; } }, [currentView]); // Artistic color palette - inspired by watercolors and sketching const colorPalettes = { sketch: ['#2D3436', '#636E72', '#B2BEC3', '#DDD6C5', '#F4E4BC'], warm: ['#E17055', '#FDCB6E', '#E84393', '#FD79A8', '#FDCB6E'], cool: ['#0984E3', '#74B9FF', '#00B894', '#55EFC4', '#A29BFE'], earth: ['#8D6E63', '#D7CCC8', '#6C5B7B', '#C06C84', '#F8B195'], vintage: ['#4A4A4A', '#8B7355', '#C7956D', '#E4C5AF', '#F2E7D5'] }; const [currentPalette, setCurrentPalette] = useState('sketch'); const startDrawing = (e) => { e.preventDefault(); setIsDrawing(true); const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); const rect = canvas.getBoundingClientRect(); const touch = e.touches ? e.touches[0] : e; const x = touch.clientX - rect.left; const y = touch.clientY - rect.top; ctx.beginPath(); ctx.moveTo(x, y); }; const draw = (e) => { e.preventDefault(); if (!isDrawing) return; const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); const rect = canvas.getBoundingClientRect(); const touch = e.touches ? e.touches[0] : e; const x = touch.clientX - rect.left; const y = touch.clientY - rect.top; if (currentTool === 'eraser') { ctx.globalCompositeOperation = 'destination-out'; ctx.lineWidth = brushSize * 2; } else { ctx.globalCompositeOperation = 'source-over'; ctx.lineWidth = brushSize; ctx.strokeStyle = currentColor; } // Add slight randomness for more natural strokes const randomOffset = Math.random() * 0.5 - 0.25; ctx.lineTo(x + randomOffset, y + randomOffset); ctx.stroke(); ctx.beginPath(); ctx.moveTo(x + randomOffset, y + randomOffset); }; const stopDrawing = () => { setIsDrawing(false); }; const clearCanvas = () => { const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); // Redraw paper texture ctx.fillStyle = '#FEFEFE'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.globalAlpha = 0.05; for (let i = 0; i < 50; i++) { ctx.fillStyle = Math.random() > 0.5 ? '#E8E8E8' : '#F5F5F5'; ctx.fillRect(Math.random() * canvas.width, Math.random() * canvas.height, 2, 2); } ctx.globalAlpha = 1; }; const createTrip = () => { if (tripForm.title && tripForm.startDate && tripForm.endDate) { const newTrip = { id: Date.now(), ...tripForm, days: [] }; setTrips([...trips, newTrip]); setTripForm({ title: '', cover: '', startDate: '', endDate: '' }); setCurrentView('home'); } }; const openTrip = (trip) => { setCurrentTrip(trip); setCurrentView('review-book'); setReviewPage(0); }; const addDailyEntry = () => { if (currentTrip) { const canvas = canvasRef.current; const drawingData = canvas.toDataURL(); const newDay = { id: Date.now(), date: new Date().toISOString().split('T')[0], drawing: drawingData, description: dayForm.description, images: dayForm.images }; const updatedTrip = { ...currentTrip, days: [...currentTrip.days, newDay] }; setTrips(trips.map(t => t.id === currentTrip.id ? updatedTrip : t)); setCurrentTrip(updatedTrip); setDayForm({ description: '', images: [] }); setCurrentView('review-book'); } }; const renderHome = () => (
Capture your journey in art
{new Date(trip.startDate).toLocaleDateString()} - {new Date(trip.endDate).toLocaleDateString()}
Your creative journey awaits
Start your first travel sketchbook
Add inspiration photos
Reference images for your sketches
No sketch yet
{currentTrip.days[reviewPage]?.description || 'No notes for this day...'}
Your canvas awaits
Start sketching your travel memories