class PixelGrid { constructor() { this.gridSize = 16; this.currentColor = '#ef4444'; // Default red this.currentTool = 'paint'; this.brightness = 5; this.isDrawing = false; this.colors = [ '#ef4444', '#f97316', '#eab308', '#22c55e', '#3b82f6', '#6366f1', '#8b5cf6', '#ec4899', '#ffffff', '#000000', '#64748b', '#06b6d4' ]; this.init(); } init() { this.createColorPalette(); this.createGrid(); this.createPreviewGrid(); this.setupEventListeners(); } createColorPalette() { const paletteContainer = document.getElementById('colorPalette'); paletteContainer.innerHTML = ''; this.colors.forEach(color => { const colorSwatch = document.createElement('div'); colorSwatch.className = `color-swatch ${color === this.currentColor ? 'active' : ''}`; colorSwatch.style.backgroundColor = color; colorSwatch.addEventListener('click', () => this.selectColor(color, colorSwatch)); paletteContainer.appendChild(colorSwatch); }); } selectColor(color, element) { this.currentColor = color; // Update active state document.querySelectorAll('.color-swatch').forEach(swatch => { swatch.classList.remove('active'); }); element.classList.add('active'); } createGrid() { const gridContainer = document.getElementById('pixelGrid'); gridContainer.innerHTML = ''; gridContainer.className = `grid grid-cols-${this.gridSize} gap-1 mx-auto`; for (let i = 0; i < this.gridSize * this.gridSize; i++) { const pixel = document.createElement('div'); pixel.className = 'pixel bg-gray-900'; pixel.dataset.index = i; pixel.addEventListener('mousedown', (e) => this.startDrawing(e, pixel)); pixel.addEventListener('mouseenter', (e) => this.draw(e, pixel)); pixel.addEventListener('touchstart', (e) => this.startDrawing(e, pixel)); pixel.addEventListener('touchmove', (e) => this.touchDraw(e)); gridContainer.appendChild(pixel); } } createPreviewGrid() { const previewContainer = document.getElementById('previewGrid'); previewContainer.innerHTML = ''; previewContainer.className = `grid grid-cols-8 gap-1 mx-auto max-w-md`; for (let i = 0; i < 64; i++) { const pixel = document.createElement('div'); pixel.className = 'pixel bg-gray-900'; pixel.dataset.previewIndex = i; previewContainer.appendChild(pixel); } startDrawing(e, pixel) { e.preventDefault(); this.isDrawing = true; this.draw(e, pixel); } draw(e, pixel) { if (!this.isDrawing && e.type === 'mouseenter') return; if (this.currentTool === 'paint') { pixel.style.backgroundColor = this.currentColor; this.updatePreview(); } else if (this.currentTool === 'eraser') { pixel.style.backgroundColor = '#1f2937'; this.updatePreview(); } } touchDraw(e) { e.preventDefault(); const touch = e.touches[0]; const element = document.elementFromPoint(touch.clientX, touch.clientY); if (element && element.classList.contains('pixel')) { this.draw(e, element); } } updatePreview() { const mainGrid = document.querySelectorAll('#pixelGrid .pixel'); const previewGrid = document.querySelectorAll('#previewGrid .pixel'); // Sample main grid to fit preview (8x8) const sampleStep = Math.floor(this.gridSize / 8); previewGrid.forEach((previewPixel, index) => { const row = Math.floor(index / 8); const col = index % 8; const mainIndex = (row * sampleStep) * this.gridSize + (col * sampleStep); if (mainGrid[mainIndex]) { previewPixel.style.backgroundColor = mainGrid[mainIndex].style.backgroundColor || '#1f2937'; } }); } clearGrid() { document.querySelectorAll('#pixelGrid .pixel').forEach(pixel => { pixel.style.backgroundColor = '#1f2937'; }); this.updatePreview(); } randomizeGrid() { document.querySelectorAll('#pixelGrid .pixel').forEach(pixel => { if (Math.random() > 0.7) { const randomColor = this.colors[Math.floor(Math.random() * this.colors.length)]; pixel.style.backgroundColor = randomColor; } else { pixel.style.backgroundColor = '#1f2937'; } }); this.updatePreview(); } setupEventListeners() { // Mouse up event for entire document document.addEventListener('mouseup', () => { this.isDrawing = false; }); // Tool buttons document.getElementById('paintTool').addEventListener('click', () => { this.currentTool = 'paint'; document.getElementById('paintTool').classList.add('bg-blue-600'); document.getElementById('eraserTool').classList.remove('bg-gray-600'); document.getElementById('eraserTool').classList.add('bg-gray-500'); }); document.getElementById('eraserTool').addEventListener('click', () => { this.currentTool = 'eraser'; document.getElementById('eraserTool').classList.add('bg-gray-600'); document.getElementById('paintTool').classList.remove('bg-blue-600'); document.getElementById('paintTool').classList.add('bg-blue-500'); }); // Control buttons document.getElementById('clearBtn').addEventListener('click', () => this.clearGrid()); document.getElementById('randomBtn').addEventListener('click', () => this.randomizeGrid()); // Grid size selector document.getElementById('gridSize').addEventListener('change', (e) => { this.gridSize = parseInt(e.target.value.split('x')[0]); this.createGrid(); this.updatePreview(); }); // Brightness control document.getElementById('brightness').addEventListener('input', (e) => { this.brightness = parseInt(e.target.value); this.updateBrightness(); }); // Prevent context menu on grid document.getElementById('pixelGrid').addEventListener('contextmenu', (e) => { e.preventDefault(); }); } updateBrightness() { const brightnessValue = this.brightness / 5; document.querySelectorAll('#pixelGrid .pixel').forEach(pixel => { if (pixel.style.backgroundColor && pixel.style.backgroundColor !== 'rgb(31, 41, 55)') { pixel.style.filter = `brightness(${brightnessValue})`; } } } // Initialize the pixel grid when DOM is loaded document.addEventListener('DOMContentLoaded', () => { new PixelGrid(); });