about summary refs log tree commit diff stats
path: root/js/pixel-art/pixel/app.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/pixel-art/pixel/app.js')
-rw-r--r--js/pixel-art/pixel/app.js186
1 files changed, 186 insertions, 0 deletions
diff --git a/js/pixel-art/pixel/app.js b/js/pixel-art/pixel/app.js
new file mode 100644
index 0000000..087801c
--- /dev/null
+++ b/js/pixel-art/pixel/app.js
@@ -0,0 +1,186 @@
+const canvas = document.getElementById('canvas');
+const ctx = canvas.getContext('2d');
+const defaultGridWidth = 16;
+const defaultGridHeight = 16;
+let gridWidth = defaultGridWidth;
+let gridHeight = defaultGridHeight;
+let cellSize = 16;
+let colorHistory = [];
+let currentColor = '#000000';
+let grid = Array(gridWidth).fill().map(() => Array(gridHeight).fill(null));
+let offsetX = 0;
+let offsetY = 0;
+
+// Event Listeners
+canvas.addEventListener('click', handleCanvasClick);
+document.getElementById('colorPicker').addEventListener('input', handleColorChange);
+document.getElementById('gridWidth').addEventListener('change', updateGridSize);
+document.getElementById('gridHeight').addEventListener('change', updateGridSize);
+document.getElementById('resetBtn').addEventListener('click', handleReset);
+document.getElementById('exportBtn').addEventListener('click', exportToPNG);
+window.addEventListener('keydown', handlePan);
+
+// Initialization
+resizeCanvas();
+loadFromLocalStorage();
+
+// Functions
+function initializeGrid() {
+    grid = Array(gridWidth).fill().map(() => Array(gridHeight).fill(null));
+}
+
+function resizeCanvas() {
+    canvas.width = window.innerWidth;
+    canvas.height = window.innerHeight;
+    centerGrid();
+    drawGrid();
+}
+
+function centerGrid() {
+    offsetX = Math.max((canvas.width - (gridWidth * cellSize)) / 2, 0);
+    offsetY = Math.max((canvas.height - (gridHeight * cellSize)) / 2, 0);
+}
+
+function drawGrid() {
+    ctx.fillStyle = 'teal';
+    ctx.fillRect(0, 0, canvas.width, canvas.height);
+
+    ctx.strokeStyle = '#888888';
+    for (let x = 0; x < gridWidth; x++) {
+        for (let y = 0; y < gridHeight; y++) {
+            ctx.fillStyle = grid[x][y] || '#f7f7f7';
+            ctx.fillRect(x * cellSize + offsetX, y * cellSize + offsetY, cellSize, cellSize);
+            ctx.strokeRect(x * cellSize + offsetX, y * cellSize + offsetY, cellSize, cellSize);
+        }
+    }
+}
+
+function addToColorHistory(color) {
+    if (colorHistory.includes(color)) return;
+    if (colorHistory.length >= 10) colorHistory.shift();
+    colorHistory.push(color);
+    renderColorHistory();
+}
+
+function renderColorHistory() {
+    const historyDiv = document.getElementById('colorHistory');
+    historyDiv.innerHTML = '';
+    colorHistory.forEach(color => {
+        const colorDiv = document.createElement('div');
+        colorDiv.style.backgroundColor = color;
+        colorDiv.addEventListener('click', () => {
+            currentColor = color;
+            document.getElementById('colorPicker').value = color;
+        });
+        historyDiv.appendChild(colorDiv);
+    });
+}
+
+function handleColorChange() {
+    currentColor = document.getElementById('colorPicker').value;
+    addToColorHistory(currentColor);
+    saveToLocalStorage();
+}
+
+function handleReset() {
+    gridWidth = defaultGridWidth;
+    gridHeight = defaultGridHeight;
+    initializeGrid();
+    centerGrid();
+    drawGrid();
+    localStorage.removeItem('pixelArtConfig');
+    colorHistory = [];
+    renderColorHistory();
+    document.getElementById('gridWidth').value = gridWidth;
+    document.getElementById('gridHeight').value = gridHeight;
+    alert("Grid reset, color history cleared, and local storage cleared.");
+}
+
+function handlePan(e) {
+    const step = cellSize;
+    if (e.key === 'ArrowUp') offsetY += step;
+    if (e.key === 'ArrowDown') offsetY -= step;
+    if (e.key === 'ArrowLeft') offsetX += step;
+    if (e.key === 'ArrowRight') offsetX -= step;
+    drawGrid();
+}
+
+function updateGridSize() {
+    gridWidth = parseInt(document.getElementById('gridWidth').value);
+    gridHeight = parseInt(document.getElementById('gridHeight').value);
+    initializeGrid();
+    centerGrid();
+    drawGrid();
+    saveToLocalStorage();
+}
+
+function saveToLocalStorage() {
+    const gridData = {
+        gridWidth: gridWidth,
+        gridHeight: gridHeight,
+        cellSize: cellSize,
+        colorHistory: colorHistory,
+        currentColor: currentColor,
+        grid: grid,
+    };
+    localStorage.setItem('pixelArtConfig', JSON.stringify(gridData));
+}
+
+function loadFromLocalStorage() {
+    const savedData = localStorage.getItem('pixelArtConfig');
+    if (savedData) {
+        const gridData = JSON.parse(savedData);
+        gridWidth = gridData.gridWidth || 10;
+        gridHeight = gridData.gridHeight || 10;
+        cellSize = gridData.cellSize || 16;
+        colorHistory = gridData.colorHistory || [];
+        currentColor = gridData.currentColor || '#000000';
+        grid = gridData.grid || Array(gridWidth).fill().map(() => Array(gridHeight).fill(null));
+        document.getElementById('gridWidth').value = gridWidth;
+        document.getElementById('gridHeight').value = gridHeight;
+        document.getElementById('colorPicker').value = currentColor;
+        centerGrid();
+        drawGrid();
+    } else {
+        initializeGrid();
+        centerGrid();
+        drawGrid();
+    }
+}
+
+function exportToPNG() {
+    const tempCanvas = document.createElement('canvas');
+    const tempCtx = tempCanvas.getContext('2d');
+    tempCanvas.width = gridWidth * cellSize;
+    tempCanvas.height = gridHeight * cellSize;
+
+    for (let x = 0; x < gridWidth; x++) {
+        for (let y = 0; y < gridHeight; y++) {
+            tempCtx.fillStyle = grid[x][y] || 'transparent';
+            tempCtx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);
+        }
+    }
+
+    tempCanvas.toBlob(blob => {
+        const link = document.createElement('a');
+        link.href = URL.createObjectURL(blob);
+        link.download = 'pixel-art.png';
+        link.click();
+    });
+}
+
+function handleCanvasClick(e) {
+    const rect = canvas.getBoundingClientRect();
+    const x = Math.floor((e.clientX - rect.left - offsetX) / cellSize);
+    const y = Math.floor((e.clientY - rect.top - offsetY) / cellSize);
+    
+    if (x >= 0 && x < gridWidth && y >= 0 && y < gridHeight) {
+        if (e.detail === 2) {  // Double-click resets the cell
+            grid[x][y] = null;
+        } else {  // Single-click paints the cell with the current color
+            grid[x][y] = currentColor;
+        }
+        drawGrid();
+        saveToLocalStorage();
+    }
+}
\ No newline at end of file