Last Updated : 27 Jul, 2025
A Pixel Art Maker lets users create art by colouring squares on a grid, like retro pixel graphics. This project uses TypeScript and DOM manipulation for a fun and creative experience.
What We’re Going to CreateWe are going to create a pixel Art maker with the following components.
This code creates a simple interactive grid where users can change the grid size, pick a color, and reset the grid. The layout is styled using CSS.
HTML
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: auto;
}
body {
background: #fff;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.opts {
padding: 20px;
margin-bottom: 20px;
display: flex;
align-items: center;
}
.btn,
.clr,
.sz {
height: 30px;
padding: 0 20px;
}
.clr {
width: 100px;
margin: 0 40px;
}
.grid {
--sz: 4;
background: #000;
width: 100vh;
height: 85vh;
display: grid;
grid-template-columns: repeat(var(--sz), 1fr);
grid-template-rows: repeat(var(--sz), 1fr);
gap: 3px;
padding: 3px;
}
.cell {
background: #393939;
border-radius: 2px;
}
</style>
</head>
<body>
<div class="opts">
<button class="btn">Reset</button>
<input type="color" value="#ffa500" class="clr">
<input type="number" value="20" class="sz">
</div>
<div class="grid"></div>
<script defer src="main.js"></script>
</body>
</html>
In this Example
This code creates a dynamic pixel art grid, enabling users to draw by hovering or clicking, with adjustable grid size and color options. It includes event handling for user interactions and grid reset functionality.
JavaScript
const gCont = document.querySelector<HTMLDivElement>(".grid");
const gSize = document.querySelector<HTMLInputElement>('.sz');
const gColor = document.querySelector<HTMLInputElement>('.clr');
const gReset = document.querySelector<HTMLButtonElement>('.btn');
if (!gCont || !gSize || !gColor || !gReset) {
throw new Error("Missing required DOM elements");
}
let gridSize: number = parseInt(gSize.value);
let isDrawing: boolean = false;
function createGrid(): void {
gCont.style.setProperty("--sz", gridSize.toString());
gCont.innerHTML = "";
for (let i = 0; i < gridSize * gridSize; i++) {
const cell = document.createElement("div");
cell.classList.add("cell");
cell.addEventListener('mouseenter', () => paintCell(cell));
cell.addEventListener('mousedown', () => clickCell(cell));
gCont.appendChild(cell);
}
}
function paintCell(cell: HTMLDivElement): void {
if (!isDrawing) return;
cell.style.backgroundColor = gColor.value;
}
function clickCell(cell: HTMLDivElement): void {
cell.style.backgroundColor = gColor.value;
}
window.addEventListener('mousedown', () => {
isDrawing = true;
});
window.addEventListener('mouseup', () => {
isDrawing = false;
});
function resetGrid(): void {
createGrid();
}
gReset.addEventListener('click', resetGrid);
gSize.addEventListener('change', () => {
gridSize = parseInt(gSize.value);
resetGrid();
});
createGrid();
In this example
Now You need to convert the TypeScript file into JavaScript to render by browser. Use one of the following command.
npx tsc codes.ts
tsc codes.ts
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: auto;
}
body {
background: #fff;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.opts {
padding: 20px;
margin-bottom: 20px;
display: flex;
align-items: center;
}
.btn,
.clr,
.sz {
height: 30px;
padding: 0 20px;
}
.clr {
width: 100px;
margin: 0 40px;
}
.grid {
--sz: 4;
background: #000;
width: 100vh;
height: 85vh;
display: grid;
grid-template-columns: repeat(var(--sz), 1fr);
grid-template-rows: repeat(var(--sz), 1fr);
gap: 3px;
padding: 3px;
}
.cell {
background: #393939;
border-radius: 2px;
}
</style>
</head>
<body>
<div class="opts">
<button class="btn">Reset</button>
<input type="color" value="#ffa500" class="clr">
<input type="number" value="20" class="sz">
</div>
<div class="grid"></div>
<script defer>
const gCont = document.querySelector(".grid");
const gSize = document.querySelector('.sz');
const gColor = document.querySelector('.clr');
const gReset = document.querySelector('.btn');
if (!gCont || !gSize || !gColor || !gReset) {
throw new Error("Missing required DOM elements");
}
let gridSize = parseInt(gSize.value);
let isDrawing = false;
function createGrid() {
gCont.style.setProperty("--sz", gridSize.toString());
gCont.innerHTML = "";
for (let i = 0; i < gridSize * gridSize; i++) {
const cell = document.createElement("div");
cell.classList.add("cell");
cell.addEventListener('mouseenter', () => paintCell(cell));
cell.addEventListener('mousedown', () => clickCell(cell));
gCont.appendChild(cell);
}
}
function paintCell(cell) {
if (!isDrawing) return;
cell.style.backgroundColor = gColor.value;
}
function clickCell(cell) {
cell.style.backgroundColor = gColor.value;
}
window.addEventListener('mousedown', () => {
isDrawing = true;
});
window.addEventListener('mouseup', () => {
isDrawing = false;
});
function resetGrid() {
createGrid();
}
gReset.addEventListener('click', resetGrid);
gSize.addEventListener('change', () => {
gridSize = parseInt(gSize.value);
resetGrid();
});
createGrid();
</script>
</body>
</html>
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4