MarkTheArtist's picture
Make me a litebright simulation
80226f6 verified
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();
});