JavaScript Drawing Application Source Code

How To Create a Drawing Application in JavaScript, HTML and CSS

How To Create a Drawing Application in JavaScript, HTML and CSS


In this JavaScript Tutorial, we will see how to create a Drawing application using  JavaScript, HTML5, CSS3.
In this project tutorial we will build a painting project with multiple drawing tools, shapes, colors, and even undo/redo functionality. 

What We Are Gonna Use In This Project:

- JavaScript Programming Language.
- HTML and CSS.
- Font-awesome.
- Visual Studio Editor.






Project Source Code:



     - Canvas History Recorder

Captures the current canvas state as a data URL and stores it in the undo stack for later restoration.


// Save the current drawing to history so we can undo later
function saveState() {
// Convert canvas to a data URL (like a photo of the drawing)
undoStack.push(canvas.toDataURL());
// Clear redo history when new drawing happens
// (can't redo after drawing something new)
redoStack = [];
}



     - Canvas State Restorer
    
Takes a saved canvas state and redraws it on the canvas, clearing any existing content first.

// Put a saved drawing back on the canvas (for undo/redo)
function restoreState(state) {
// Create a new image from the saved data
const img = new Image();
img.src = state;
// When image loads, draw it on the canvas
img.onload = () => {
// Clear canvas first
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw the saved state
ctx.drawImage(img, 0, 0);
};
}




     - Drawing Session Initiator

Activates drawing mode when mouse is pressed down and captures the starting coordinates for the drawing operation.


// Start drawing when mouse button is pressed down
function startDrawing(e) {
isDrawing = true;
// Get mouse position and remember it
[lastX, lastY] = [e.offsetX, e.offsetY];

// For shapes, take a snapshot of current canvas
// This helps us show a preview while dragging
if (currentShape !== 'freehand') {
snapshot = ctx.getImageData(0, 0, canvas.width, canvas.height);
}
}



     - Main Drawing Function

Handles all drawing operations based on current tool and shape settings, managing different drawing modes like freehand, lines, rectangles, and circles.


// Do the actual drawing as mouse moves
function draw(e) {
// Don't do anything if we're not in drawing mode
if (!isDrawing) return;

// Get current mouse position
const x = e.offsetX;
const y = e.offsetY;

// Set color based on current tool
// If using eraser, use background color (to "erase")
// Otherwise use the selected drawing color
ctx.strokeStyle = currentTool === 'eraser' ? bgColor : currentColor;
ctx.fillStyle = currentTool === 'eraser' ? bgColor : currentColor;

// Set line thickness and style based on selected tool
if (currentTool === 'brush') {
// Brush is thicker than pencil
ctx.lineWidth = brushSize.value * 2;
ctx.lineCap = 'round'; // Round end caps for smooth lines
ctx.lineJoin = 'round'; // Round corners for smooth lines
} else if (currentTool === 'pencil' || currentTool === 'eraser') {
ctx.lineWidth = brushSize.value;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
}

// Do different drawing based on selected shape
switch (currentShape) {
case 'freehand':
// Free drawing - follow the mouse movement exactly
ctx.beginPath(); // Start a new line
ctx.moveTo(lastX, lastY); // Move to where we started
ctx.lineTo(x, y); // Draw to current position
ctx.stroke(); // Actually draw the line
[lastX, lastY] = [x, y]; // Update position for next move
break;

case 'line':
// Straight line - from start point to current mouse position
ctx.putImageData(snapshot, 0, 0); // Restore canvas to before drag
ctx.beginPath(); // Start a new line
ctx.moveTo(lastX, lastY); // Move to start position
ctx.lineTo(x, y); // Draw to current position
ctx.stroke(); // Actually draw the line
break;

case 'rectangle':
// Rectangle - from start point with width/height to mouse
ctx.putImageData(snapshot, 0, 0); // Restore canvas to before drag
const width = x - lastX; // Calculate width based on mouse
const height = y - lastY; // Calculate height based on mouse

// Fill the rectangle if fill option is on
if (fillShape) {
ctx.fillRect(lastX, lastY, width, height);
}

// Always draw the outline
ctx.strokeRect(lastX, lastY, width, height);
break;

case 'circle':
// Circle - center at start point, size to mouse position
ctx.putImageData(snapshot, 0, 0); // Restore canvas to before drag

// Calculate radius (distance from center to mouse)
const radius = Math.sqrt(Math.pow(x - lastX, 2) + Math.pow(y - lastY, 2));

ctx.beginPath(); // Start a new shape
ctx.arc(lastX, lastY, radius, 0, 2 * Math.PI); // Draw full circle

// Fill the circle if fill option is on
if (fillShape) { ctx.fill(); }

// Always draw the outline
ctx.stroke();
break;

}

}




     - Drawing Session Finalizer

Deactivates drawing mode when mouse is released and saves the current state to the undo history.


// Stop drawing when mouse button is released
function stopDrawing() {
if (isDrawing) {
isDrawing = false;
// Save to history when finished drawing
// (so we can undo if needed)
saveState();
}
}



     - Previous State Restorer

Moves backward through the drawing history by one step, allowing users to reverse their last action.


// Go back one step in drawing history
function undo() {
// Need at least 2 items in stack (original blank + at least one drawing)
if (undoStack.length > 1) {
// Move current drawing to redo stack
redoStack.push(undoStack.pop());
// Show the previous drawing
restoreState(undoStack[undoStack.length - 1]);
}
}




     - Forward State Restorer

Moves forward through the drawing history by one step, allowing users to restore previously undone actions.


// Go forward one step in drawing history
function redo() {
if (redoStack.length > 0) {
// Get the most recent redo state
const stateToRedo = redoStack.pop();
// Add it back to the undo history
undoStack.push(stateToRedo);
// Show this drawing
restoreState(stateToRedo);
}
}



     - Background Color Updater

Updates the canvas background color using the selected color from the color picker and refreshes the display.


// Change the canvas background color
function changeBackgroundColor() {
// Get color from the color picker
const newColor = customColorPicker.value;
bgColor = newColor;
// Apply by clearing canvas with new background color
clearCanvas();
}



     - Canvas Content Eraser

Completely clears the canvas and fills it with the current background color, then saves this blank state.


// Clear everything from the canvas
function clearCanvas() {
// Fill entire canvas with background color
ctx.fillStyle = bgColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Save this blank state to history
saveState();
}



     - Active Tool Selector

Updates the current tool setting and provides visual feedback by highlighting the selected tool button.


// Highlight the active tool button
function setActiveTool(toolName) {
currentTool = toolName;
// Remove highlight from all buttons first
document.querySelectorAll('.toolbar button').
forEach(btn => btn.classList.remove('active'));
// Add highlight to selected tool button
document.getElementById(`${toolName}Btn`).classList.add('active');
}



     - Drawing Export Handler

Converts the current canvas content to a PNG image and triggers a download for the user.


// Save drawing as a PNG image file
function saveCanvas() {
// Create a download link
const link = document.createElement('a');
link.download = 'drawing.png'; // File name
// Get the canvas data as an image URL
link.href = canvas.toDataURL();
// Trigger the download
link.click();
}











JavaScript Drawing Application Source Code - 1

JavaScript Drawing Application Source Code - 2

JavaScript Drawing Application Source Code - 3

JavaScript Drawing Application Source Code - 4

JavaScript Drawing Application Source Code - 5

JavaScript Drawing Application Source Code - 6

JavaScript Drawing Application Source Code - 7


if you want the source code click on the download button below




disclaimer: you will get the source code with the database script and to make it work in your machine is your responsibility and to debug any error/exception is your responsibility this project is for the students who want to see an example and read the code not to get and run.






Share this

Related Posts

Previous
Next Post »