DEV Community

lemon
lemon

Posted on

Draw Pixel Art with Vanilla JS — A Step-by-Step Guide

Draw Pixel Art with Vanilla JS

Posted on Jul 15, 2026

Hi there! I\'m a frontend developer and learning to become a game developer. I got very stuck when searching for art and sprites for my game, so I decided to draw them with my JavaScript skills. Here is my approach — it\'s very simple and requires zero dependencies:

Prepare a Canvas Element

<div style="width: 100vw; height: 100vh; display: flex; justify-content: center; align-items: center;">
  <div>
    <canvas id="canvas" width="512" height="512" style="width: 512px; height: 512px;"></canvas>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Define Your Color Palette

const colors = [
    "#c6bfbe",  // 0 - light gray
    "#040309",  // 1 - black
    "#e0e6e9",  // 2 - white
    "#9d919d",  // 3 - gray
    "#b0813f",  // 4 - brown
    "#cf7f33",  // 5 - orange
    "#adb6b1",  // 6 - greenish gray
    "#1d1f29"   // 7 - dark blue
];
Enter fullscreen mode Exit fullscreen mode

Create the Pixel Map

Each key follows the format x_y and maps to a color index from the palette:

const pixelMap = {
    "2_3": 1,
    "2_4": 1,
    "2_5": 1,
    "2_6": 1,
    "2_8": 1,
    "2_9": 1,
    "3_3": 1,
    "3_4": 3,
    "3_5": 1,
    "3_6": 4,
    "3_7": 1,
    "3_8": 6,
    "3_9": 0,
    "4_2": 1,
    "4_3": 1,
    "4_4": 1,
    "4_5": 1,
    "4_6": 4,
    "4_7": 1,
    "4_8": 1,
    "4_9": 1,
    "5_2": 1,
    "5_3": 2,
    "5_4": 1,
    "5_5": 1,
    "5_6": 1,
    "5_7": 2,
    "5_8": 1,
    "5_9": 1,
    "6_2": 1,
    "6_3": 1,
    "6_4": 1,
    "6_5": 1,
    "6_6": 1,
    "6_7": 1,
    "6_8": 1,
    "6_9": 1,
    "7_3": 1,
    "7_4": 5,
    "7_5": 1,
    "7_6": 1,
    "7_7": 5,
    "7_8": 1,
    "8_4": 1,
    "8_5": 1,
    "8_6": 1,
    "8_7": 1
};
Enter fullscreen mode Exit fullscreen mode

Draw the Pixel Art

const canvas = document.getElementById("canvas");
const size = 16; // 16x16 grid
const baseSize = Math.round(canvas.width / size);
const ctx = canvas.getContext("2d");

// Fill background
ctx.fillStyle = "#F0F0F0";
ctx.fillRect(0, 0, canvas.width, canvas.height);

// Draw each pixel
for (const key in pixelMap) {
    const [x, y] = key.split("_");
    ctx.fillStyle = colors[pixelMap[key]];
    ctx.fillRect(+x * baseSize, +y * baseSize, baseSize, baseSize);
}
Enter fullscreen mode Exit fullscreen mode

Tada! Here is the result — a simple pixel character drawn entirely with vanilla JavaScript:

Pixel Art Result

Make It Interactive

Let\'s add a click-to-draw feature so users can create their own pixel art:

let currentColor = 1; // Default to black
let isDrawing = false;

// Handle mouse events
canvas.addEventListener("mousedown", () => isDrawing = true);
canvas.addEventListener("mouseup", () => isDrawing = false);
canvas.addEventListener("mouseleave", () => isDrawing = false);

canvas.addEventListener("mousemove", (e) => {
    if (!isDrawing) return;

    const rect = canvas.getBoundingClientRect();
    const x = Math.floor((e.clientX - rect.left) / baseSize);
    const y = Math.floor((e.clientY - rect.top) / baseSize);

    ctx.fillStyle = colors[currentColor];
    ctx.fillRect(x * baseSize, y * baseSize, baseSize, baseSize);

    // Update pixel map
    pixelMap[`${x}_${y}`] = currentColor;
});

// Color picker
const colorButtons = document.createElement("div");
colorButtons.style.display = "flex";
colorButtons.style.gap = "8px";
colorButtons.style.marginTop = "16px";

colors.forEach((color, index) => {
    const btn = document.createElement("button");
    btn.style.width = "32px";
    btn.style.height = "32px";
    btn.style.backgroundColor = color;
    btn.style.border = index === currentColor ? "3px solid #333" : "1px solid #ccc";
    btn.style.cursor = "pointer";
    btn.onclick = () => {
        currentColor = index;
        // Update border styles
        Array.from(colorButtons.children).forEach((b, i) => {
            b.style.border = i === index ? "3px solid #333" : "1px solid #ccc";
        });
    };
    colorButtons.appendChild(btn);
});

document.body.appendChild(colorButtons);
Enter fullscreen mode Exit fullscreen mode

Export Your Creation

function exportPixelArt() {
    const link = document.createElement("a");
    link.download = "my-pixel-art.png";
    link.href = canvas.toDataURL("image/png");
    link.click();
}

// Add export button
const exportBtn = document.createElement("button");
exportBtn.textContent = "Export PNG";
exportBtn.style.marginTop = "16px";
exportBtn.style.padding = "8px 16px";
exportBtn.onclick = exportPixelArt;
document.body.appendChild(exportBtn);
Enter fullscreen mode Exit fullscreen mode

Load Pixel Art from JSON

function loadPixelArt(jsonData) {
    // Clear canvas
    ctx.fillStyle = "#F0F0F0";
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // Draw from data
    for (const key in jsonData) {
        const [x, y] = key.split("_");
        ctx.fillStyle = colors[jsonData[key]];
        ctx.fillRect(+x * baseSize, +y * baseSize, baseSize, baseSize);
    }
}

// Example: load a predefined sprite
const mushroomSprite = {
    "6_4": 1, "7_4": 1, "8_4": 1,
    "5_5": 1, "6_5": 2, "7_5": 2, "8_5": 2, "9_5": 1,
    "4_6": 1, "5_6": 2, "6_6": 2, "7_6": 2, "8_6": 2, "9_6": 2, "10_6": 1,
    "4_7": 1, "5_7": 1, "6_7": 1, "7_7": 1, "8_7": 1, "9_7": 1, "10_7": 1,
    "6_8": 4, "7_8": 4, "8_8": 4,
    "6_9": 4, "7_9": 4, "8_9": 4,
    "6_10": 4, "7_10": 4, "8_10": 4
};

// Uncomment to draw: loadPixelArt(mushroomSprite);
Enter fullscreen mode Exit fullscreen mode

Tools to Speed Up Your Pixel Art Workflow

Building pixel art from code is fun, but sometimes you need a visual grid to plan your designs first. Check out Pixel Art Grid — a free online tool with customizable grids for sketching pixel art before coding it. Perfect for planning sprites, icons, and game assets.

Want to turn your pixel art into a spiral wall poster? Spiral Betty takes any image and transforms it into a stunning spiral design using Canvas-based processing — great for gifts and room decor.

For tabletop RPG fans, Token Maker lets you generate circular and square VTT tokens with custom borders and frames. All rendered with Canvas, just like the code above.

Also try Spiral Betty for an alternative spiral effect with additional filter options.

You can get more pixel art data by inspecting APIs from Pixel Art Grid. I welcome that!

Full source code available. Happy pixel drawing!

Top comments (0)