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.
Originally posted on: https://lexingtonthemes.com/tutorials/how-to-create-a-basic-drawing-tool-and-save-to-png-with-tailwind-css-and-javascript/
What is a drawing tool?
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.
Use cases
Sketching:
Quick visualization of ideas or concepts
Creating rough drafts for more complex designs
Brainstorming sessions and mind mapping
Digital Art:
Creating illustrations, paintings, and other forms of visual art
Comic book and manga creation
Character design for games or animation
Graphic Design:
Logo design and branding elements
Creating marketing materials like flyers, posters, and social media graphics
User interface (UI) and user experience (UX) design mockups
Education:
Interactive whiteboards for online teaching
Visual aids for explaining complex concepts
Student projects and assignments in art or design classes
Annotation and Markup:
Adding notes or highlights to documents or images
Collaborative editing and feedback on visual projects
Creating visual instructions or tutorials
Web Design:
Wireframing websites and web applications
Creating custom icons and graphics for web use
Designing responsive layouts and user interfaces
Photo Editing:
Retouching and enhancing photographs
Creating photo manipulations and composites
Adding text or graphics to images
Technical Drawing
Creating diagrams and flowcharts
Architectural sketches and floor plans
Engineering drawings and schematics
Game Development:
Designing game assets and sprites
Creating textures for 3D models
Concept art for game environments and characters
Data Visualization:
Creating custom charts and graphs
Designing infographics
Mapping data in visual formats
Personal Expression:
Digital journaling and scrapbooking
Creating personalized gifts or cards
Therapeutic art and self-expression
Prototyping:
Quickly visualizing product designs
Creating interactive prototypes for apps or websites
Iterating on design concepts
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.
Let’s start writing the code
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. Classes
class="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’s
id="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. Classes
class="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="w-10 h-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’s
id="brushSize"
: This is the id of the range slider input element. Attributes
min="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. Classes
class="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>
The full markup
<div>
<canvas
id="drawingCanvas"
class="w-full border shadow border-base-50 rounded-xl h-80"
></canvas>
<div class="flex flex-row items-center w-full mt-4 space-x-4">
<input type="color" id="colorPicker" class="w-10 h-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="w-full h-12 px-8 py-2 text-sm font-medium text-blue-600 rounded-full bg-blue-50 hover:bg-blue-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
>
Clear
</button>
<button
id="saveBtn"
class="w-full h-12 px-8 py-2 text-sm font-medium text-white bg-blue-600 rounded-full hover:bg-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
>
Save
</button>
</div>
</div>
Let´s write the JavaScript code
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);
}
Stopping drawing
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);
}
Saving the drawing
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();
}
Event listeners and initialization
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();
The full script
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();
Conclusion
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
Join Michael on Peerlist!
Join amazing folks like Michael and thousands of other people in tech.
Create ProfileJoin with Michael’s personal invite link.
0
3
0