Skip to content

Instantly share code, notes, and snippets.

@KutsuyaYuki
Last active April 5, 2024 23:42
Show Gist options
  • Save KutsuyaYuki/89477970a810590335ce827d7dcbb9f3 to your computer and use it in GitHub Desktop.
Save KutsuyaYuki/89477970a810590335ce827d7dcbb9f3 to your computer and use it in GitHub Desktop.
Pixel art drawing component
<div class="flex flex-col items-center justify-center min-h-screen bg-zinc-100 dark:bg-zinc-900">
<div class="flex space-x-2 p-2">
<div id="colorPalette" class="flex space-x-2">
<div class="w-6 h-6 bg-red-500 cursor-pointer"></div>
<div class="w-6 h-6 bg-green-500 cursor-pointer"></div>
<div class="w-6 h-6 bg-blue-500 cursor-pointer"></div>
<div class="w-6 h-6 bg-yellow-500 cursor-pointer"></div>
<div class="w-6 h-6 bg-purple-500 cursor-pointer"></div>
<div class="w-6 h-6 bg-pink-500 cursor-pointer"></div>
<div class="w-6 h-6 bg-black cursor-pointer"></div>
<div class="w-6 h-6 bg-white cursor-pointer"></div>
<input type="color" id="customColorPicker" class="w-6 h-6 cursor-pointer" />
</div>
<input
type="number"
id="canvasSizeInput"
class="w-20 p-1 border rounded bg-zinc-100 dark:bg-zinc-900 text-white appearance-none"
/>
</div>
<div id="pixelCanvas" class="grid grid-cols-8 gap-1 p-4 bg-white dark:bg-zinc-800"></div>
<div class="flex space-x-2 mt-4">
<button
id="downloadBtn"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
>
Download as SVG
</button>
<button
id="resetBtn"
class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
>
Reset
</button>
</div>
</div>
<script>
let canvasSize = 8; // Default canvas size
const pixelCanvas = document.getElementById('pixelCanvas');
let currentColor = '#000'; // Default color
let isPainting = false; // Drag to paint
function generateCanvas(size) {
pixelCanvas.innerHTML = ''; // Clear existing canvas
pixelCanvas.style.gridTemplateColumns = `repeat(${size}, 1.5rem)`; // Adjust grid based on size
for (let i = 0; i < size * size; i++) {
const pixel = document.createElement('div');
pixel.classList.add('w-6', 'h-6', 'bg-zinc-300', 'dark:bg-zinc-700', 'cursor-pointer');
pixel.addEventListener('mousedown', () => {
isPainting = true;
pixel.style.backgroundColor = currentColor;
});
pixel.addEventListener('mouseover', () => {
if (isPainting) {
pixel.style.backgroundColor = currentColor;
}
});
pixel.addEventListener('mouseup', () => isPainting = false);
pixelCanvas.appendChild(pixel);
}
}
// Initial canvas generation
generateCanvas(canvasSize);
// Disable painting when mouse leaves the canvas
pixelCanvas.addEventListener('mouseleave', () => isPainting = false);
// Palette color selection
document.getElementById('colorPalette').addEventListener('click', (e) => {
if (e.target !== e.currentTarget) {
currentColor = window.getComputedStyle(e.target).backgroundColor;
}
});
// Custom color picker
document.getElementById('customColorPicker').addEventListener('input', (e) => {
currentColor = e.target.value;
});
// Set custom canvas size
document.getElementById('canvasSizeInput').addEventListener('change', (e) => {
const newSize = parseInt(e.target.value);
if (!isNaN(newSize) && newSize > 0) {
canvasSize = newSize;
generateCanvas(canvasSize);
}
});
// Download as SVG
document.getElementById('downloadBtn').addEventListener('click', () => {
const svgContent = generateSVGContent();
const blob = new Blob([svgContent], { type: 'image/svg+xml' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.download = 'pixel-art.svg';
link.href = url;
link.click();
URL.revokeObjectURL(url);
});
// Reset canvas
document.getElementById('resetBtn').addEventListener('click', () => {
document.querySelectorAll('#pixelCanvas > div').forEach(div => {
div.style.backgroundColor = ''; // Clear the grid
});
});
// Generate SVG content from the canvas
function generateSVGContent() {
let svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${canvasSize * 10}" height="${canvasSize * 10}">`;
document.querySelectorAll('#pixelCanvas > div').forEach((div, index) => {
const color = div.style.backgroundColor || 'none';
const x = (index % canvasSize) * 10;
const y = Math.floor(index / canvasSize) * 10;
svg += `<rect x="${x}" y="${y}" width="10" height="10" fill="${color}"/>`;
});
svg += '</svg>';
return svg;
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment