Lexington has been awarded a grant from Astro, to celebrate. Get a 30% discount. Apply code LEXINGTON30 ( uppercase ) at checkout.
Today we’ll be creating a basic drawing tool using Tailwind CSS and JavaScript. We’ll be using the canvas
element to draw on the page and the toDataURL
method to save the drawing as a PNG file.
A drawing tool is a digital application or feature that allows users to create, edit, and manipulate visual content on a computer or mobile device. It typically provides a canvas or workspace where users can draw freehand using various tools like brushes, pens, or shapes. Drawing tools can range from simple sketch applications to complex professional-grade software used in graphic design, illustration, and digital art.
Sketching:
Digital Art:
Graphic Design:
Education:
Annotation and Markup:
Web Design:
Photo Editing:
Technical Drawing:
Game Development:
Data Visualization:
Personal Expression:
Prototyping:
By incorporating these various use cases, drawing tools become versatile instruments that cater to a wide range of creative, professional, and practical needs across multiple industries and personal applications.
We’ll use the canvas
element to draw on the page
Id’s
id="drawingCanvas"
: This is the id of the canvas element. It’s used to reference the element in JavaScript. We’ll use this id to access the canvas element in our JavaScript code.
Classesclass="w-full
: This is a class that sets the width of the canvas to 100% of its parent container.class="h-80"
: This is a class that sets the height of the canvas to 80 pixels.
Addding the size of the canvas to the parent container will ensure that the canvas fills the entire space available to it. Otherwise the <canvas>
element will be smaller than the parent container.<canvas
id="drawingCanvas"
class="w-full h-80">
</canvas>
We’ll use the input
element to create a color picker. Thi is a native HTML element that allows users to select and change the color of an element. You can always another lubrary like pickr.js to create a more advanced color picker. Like i am using on many of the color pickers on Colors & fonts website.
Type
type="color"
: This is the type of the color picker input element. It’s used to specify that the input element is a color picker.
Id’sid="colorPicker"
: This is the id of the color picker input element. It’s used to reference the element in JavaScript. We’ll use this id to access the color picker input element in our JavaScript code.
Classesclass="h-10"
: This is a class that sets the height of the color picker input element to 10 pixels.class="w-10"
: This is a class that sets the width of the color picker input element to 10 pixels.<input
type="color"
id="colorPicker"
class="h-10 w-10"
/>
We’ll use the input
element to create a slider for the brush size. This slider will allow users to change the size of the brush used to draw on the canvas. We’ll use the value
attribute to set the initial value of the slider. The min
and max
attributes set the minimum and maximum values for the slider, and the step
attribute sets the increment value for the slider.
Type
type="range"
: This is the type of the range input element. It’s used to specify that the input element is a range slider.
Id’sid="brushSize"
: This is the id of the range slider input element.
Attributesmin="1"
: This is an attribute that sets the minimum value of the range slider to 1.max="20"
: This is an attribute that sets the maximum value of the range slider to 20.value="5"
: This is an attribute that sets the initial value of the range slider to 5.
Classesclass="w-full"
: This is a class that sets the width of the range slider input element to 100% of its parent container. Make it full if needed, otherwise it will be smaller than the parent container.<input
type="range"
id="brushSize"
min="1"
max="20"
value="5"
class="w-full"
/>
We’ll use the button
element to create buttons for clearing the canvas and saving the drawing.
Clearing the canvas button
id="clearBtn"
: This is the id of the clear button. This button will clear the canvas when clicked.id="saveBtn"
: This is the id of the save button. This button will save the drawing when clicked.<button
id="clearBtn">
Clear
</button>
<button
id="saveBtn">
Save
</button>
<div >
<canvas
id="drawingCanvas"
class="border border-neutral-200 shadow rounded-xl w-full h-80"
></canvas>
<div class="mt-4 flex items-center space-x-4 w-full flex-row">
<input
type="color"
id="colorPicker"
class="h-10 w-10"
/>
<input
type="range"
id="brushSize"
min="1"
max="20"
value="5"
class="w-full"
/>
</div>
<div class="flex mt-8 gap-4">
<button
id="clearBtn"
class="rounded-full bg-blue-50 px-8 py-2 h-12 text-sm font-semibold text-blue-600 hover:bg-blue-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 w-full"
>Clear</button
>
<button
id="saveBtn"
class="rounded-full bg-blue-600 px-8 py-2 h-12 text-sm font-semibold text-white hover:bg-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 w-full"
>Save</button
>
</div>
</div>
We’ll use the canvas
element to draw on the page and the toDataURL
method to save the drawing as a PNG file. We’ll also use the getContext
method to get the 2D context of the canvas element. We’ll use the colorPicker
and brushSize
variables to store the color picker and brush size input elements. We’ll also use the clearBtn
and saveBtn
variables to store the clear and save buttons.
const canvas = document.getElementById("drawingCanvas");
: This is a constant variable that stores the canvas element.const ctx = canvas.getContext("2d");
: This is a constant variable that stores the 2D context of the canvas element.const colorPicker = document.getElementById("colorPicker");
: This is a constant variable that stores the color picker input element.const brushSize = document.getElementById("brushSize");
: This is a constant variable that stores the brush size input element.const clearBtn = document.getElementById("clearBtn");
: This is a constant variable that stores the clear button.const saveBtn = document.getElementById("saveBtn");
: This is a constant variable that stores the save button.let isDrawing = false;
: This is a let variable that stores the state of the drawing.const canvas = document.getElementById("drawingCanvas");
const ctx = canvas.getContext("2d");
const colorPicker = document.getElementById("colorPicker");
const brushSize = document.getElementById("brushSize");
const clearBtn = document.getElementById("clearBtn");
const saveBtn = document.getElementById("saveBtn");
let isDrawing = false;
We’ll use the resizeCanvas
function to resize the canvas element to the size of its parent container. We’ll use the canvas.width
and canvas.height
properties to get the width and height of the canvas element.
canvas.width = canvas.clientWidth;
: This line of code sets the width of the canvas element to the width of its parent container.canvas.height = canvas.clientHeight;
: This line of code sets the height of the canvas element to the height of its parent container.function resizeCanvas() {
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
}
getMousePos(canvas, e)
: This function takes two arguments, canvas
and e
, and returns an object with the x and y coordinates of the mouse position relative to the canvas element.const rect = canvas.getBoundingClientRect();
: This line of code gets the bounding rectangle of the canvas element.const scaleX = canvas.width / rect.width;
: This line of code calculates the scale factor for the x-axis.const scaleY = canvas.height / rect.height;
: This line of code calculates the scale factor for the y-axis.return {
: This line of code returns an object with the x and y coordinates of the mouse position relative to the canvas element.x: (e.clientX - rect.left) * scaleX,
: This line of code calculates the x-coordinate of the mouse position relative to the canvas element.y: (e.clientY - rect.top) * scaleY,
: This line of code calculates the y-coordinate of the mouse position relative to the canvas element.function getMousePos(canvas, e) {
const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
return {
x: (e.clientX - rect.left) * scaleX,
y: (e.clientY - rect.top) * scaleY,
};
}
startDrawing(e)
: This function is called when the user starts drawing on the canvas.isDrawing = true;
: This line of code sets the isDrawing
variable to true
.draw(e)
: This function is called when the user is drawing on the canvas.function startDrawing(e) {
isDrawing = true;
draw(e);
}
stopDrawing()
: This function is called when the user stops drawing on the canvas.isDrawing = false;
: This line of code sets the isDrawing
variable to false
.ctx.beginPath();
: This line of code clears the current path of the canvas.function stopDrawing() {
isDrawing = false;
ctx.beginPath();
}
draw(e)
: This function is called when the user is drawing on the canvas.ctx.lineWidth = brushSize.value;
: This line of code sets the line width of the canvas to the value of the brush size input element.ctx.lineCap = "round";
: This line of code sets the line cap of the canvas to “round”.ctx.strokeStyle = colorPicker.value;
: This line of code sets the stroke style of the canvas to the value of the color picker input element.const pos = getMousePos(canvas, e);
: This line of code gets the mouse position relative to the canvas element.ctx.lineTo(pos.x, pos.y);
: This line of code draws a line from the current position to the mouse position.ctx.stroke();
: This line of code strokes the path.ctx.beginPath();
: This line of code clears the current path of the canvas.ctx.moveTo(pos.x, pos.y);
: This line of code moves the current position to the mouse position.function draw(e) {
if (!isDrawing) return;
ctx.lineWidth = brushSize.value;
ctx.lineCap = "round";
ctx.strokeStyle = colorPicker.value;
const pos = getMousePos(canvas, e);
ctx.lineTo(pos.x, pos.y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(pos.x, pos.y);
}
clearCanvas()
: This function is called when the user clicks the clear button.ctx.clearRect(0, 0, canvas.width, canvas.height);
: This line of code clears the canvas by drawing a rectangle with the coordinates (0, 0) and the width and height of the canvas.function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
We’ll use the toDataURL
method to save the drawing as a PNG file.
saveDrawing()
: This function is called when the user clicks the save button.const dataURL = canvas.toDataURL("image/png");
: This line of code gets the data URL of the canvas element.const link = document.createElement("a");
: This line of code creates a new anchor element.link.download = "drawing.png";
: This line of code sets the download attribute of the anchor element to “drawing.png”.link.href = dataURL;
: This line of code sets the href attribute of the anchor element to the data URL of the canvas element.link.click();
: This line of code simulates a click on the anchor element.function saveDrawing() {
const dataURL = canvas.toDataURL("image/png");
const link = document.createElement("a");
link.download = "drawing.png";
link.href = dataURL;
link.click();
}
window.addEventListener("resize", resizeCanvas);
: This line of code adds a resize event listener to the window object.canvas.addEventListener("mousedown", startDrawing);
: This line of code adds a mousedown event listener to the canvas object.canvas.addEventListener("mousemove", draw);
: This line of code adds a mousemove event listener to the canvas object.canvas.addEventListener("mouseup", stopDrawing);
: This line of code adds a mouseup event listener to the canvas object.canvas.addEventListener("mouseout", stopDrawing);
: This line of code adds a mouseout event listener to the canvas object.clearBtn.addEventListener("click", clearCanvas);
: This line of code adds a click event listener to the clear button.saveBtn.addEventListener("click", saveDrawing);
: This line of code adds a click event listener to the save button.resizeCanvas();
: This line of code calls the resizeCanvas
function.window.addEventListener("resize", resizeCanvas);
canvas.addEventListener("mousedown", startDrawing);
canvas.addEventListener("mousemove", draw);
canvas.addEventListener("mouseup", stopDrawing);
canvas.addEventListener("mouseout", stopDrawing);
clearBtn.addEventListener("click", clearCanvas);
saveBtn.addEventListener("click", saveDrawing);
// Initialize canvas size
resizeCanvas();
const canvas = document.getElementById("drawingCanvas");
const ctx = canvas.getContext("2d");
const colorPicker = document.getElementById("colorPicker");
const brushSize = document.getElementById("brushSize");
const clearBtn = document.getElementById("clearBtn");
const saveBtn = document.getElementById("saveBtn");
let isDrawing = false;
function resizeCanvas() {
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
}
function getMousePos(canvas, e) {
const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
return {
x: (e.clientX - rect.left) * scaleX,
y: (e.clientY - rect.top) * scaleY,
};
}
function startDrawing(e) {
isDrawing = true;
draw(e);
}
function stopDrawing() {
isDrawing = false;
ctx.beginPath();
}
function draw(e) {
if (!isDrawing) return;
ctx.lineWidth = brushSize.value;
ctx.lineCap = "round";
ctx.strokeStyle = colorPicker.value;
const pos = getMousePos(canvas, e);
ctx.lineTo(pos.x, pos.y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(pos.x, pos.y);
}
function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
function saveDrawing() {
const dataURL = canvas.toDataURL("image/png");
const link = document.createElement("a");
link.download = "drawing.png";
link.href = dataURL;
link.click();
}
window.addEventListener("resize", resizeCanvas);
canvas.addEventListener("mousedown", startDrawing);
canvas.addEventListener("mousemove", draw);
canvas.addEventListener("mouseup", stopDrawing);
canvas.addEventListener("mouseout", stopDrawing);
clearBtn.addEventListener("click", clearCanvas);
saveBtn.addEventListener("click", saveDrawing);
// Initialize canvas size
resizeCanvas();
This is a simple drawing tool that demonstrates how to use Tailwind CSS and JavaScript to create a basic drawing tool and add some interactivity and basic functionality like clearing the canvas, saving, adding brush size and color pickers. It’s a great starting point for building more complex drawing tools and applications.
Hope you enjoyed this tutorial and have a great day!
/Michael Andreuzza
Get lifetime access to every theme available today for $199 and own
them forever. Plus, new themes, lifetime updates, use on unlimited
projects and enjoy lifetime support.
— No subscription required!