A simple, not fancy at all, HTML5 canvas drawing.
Features include:
- Draw on canvas with different colors and brush thickness.
- Select different brush color and thickness.
- Select eraser and erase drawing on canvas.
- Clear canvas.
Built using:
- Vue
- Canvas API
- Google Fonts - Permanent Marker
- Normalize CSS
Play around with it on CodePen
Or see it live! here
Here are the general steps to create your own Not Fancy Canvas Drawing.
We need to set the width and height of our canvas. We also add a ref
attribute so we can select the canvas element. But note, $refs
is non-reactive, so you shouldn't use in templates for data-binding.
ref is used to register a reference to an element or a child component. The reference will be registered under the parent component’s $refs object.
It's similar to vanilla JS document.querySelector('canvas')
.
<canvas
ref="myCanvas"
width="400px"
height="350px"
></canvas>
Before we create the actual drawing capability, we need to figure out which event listeners should trigger the draw. To do so, we need to access the mouse events. We want the drawing to begin when the user press down on the mouse and continue drawing as they move the mouse around. And the drawing should stop, once the mouse is unpressed. So here are the 3 events we need to handle.
mousedown
event is fired when mouse is pressed on an element.mousemove
event is fired when mouse is moved while over an element.mouseup
event is fired mouse is released over an element.
Let's add these event handler to our canvas!
<canvas ...
v-on:mousedown="onMouseDown"
v-on:mousemove="onMouseMove"
v-on:mouseup="onMouseUp"
></canvas>
Before we deal with the function call of the mouse event, let's create our draw method first.
methods: {
// 1. Get a reference to our canvas
const canvas = this.$refs.myCanvas;
// 2. Create the context that indicates the drawing is 2D
// (another context would be 3D)
const ctx = canvas.getContext('2d');
// 3. Here we configure how the drawing will look
// Draw a line with rounded end caps
ctx.lineCap = 'round'
// Create a round corner when 2 lines meet
ctx.lineJoin = 'round';
// Black Color
ctx.strokeStyle = '#000000';
// Thickness of line drawing
ctx.lineWidth = 3;
}
So we just configured how the line drawing should look like. Next, we need to configure the start and go point. The starting point is when the mouse is pressed down. The go point continues as the mouse moves. When the mouse is unpressed, it stops the drawing.
// 1. We'll store the starting points in our data
data: {
// It's at 0,0 right now,
// but this will be change where ever the mouse is pressed
startX: 0;
startY: 0;
// This will be true or false depending on the mouse event
isDrawing: false;
},
methods: {
draw(e) {
// if drawing is false, we'll stop this drawing method
// (This is called a guard clause)
if (!this.isDrawing) {
return;
}
// 2. Let's start
// (This is required since we will be using multiple colors)
ctx.beginPath();
// 3. Starting point
ctx.moveTo(this.startX, this.startY);
// 4. Go point
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
// 5. We want overwrite the starting point to be the go point
// otherwise, the starting point will always be at the same spot and
// you won't have the drawing effect.
this.startX = e.offsetX;
this.startY = e.offsetY;
}
}
Now we need to hook up the appropriate action when the mouse event is called.
methods: {
onMouseDown(e) {
// Start the drawing
this.isDrawing = true;
// We want the starting point to be where the mouse is pressed
this.startX = e.offsetX;
this.startY = e.offsetY;
},
onMouseMove(e) {
// Keep drawing, yay!
this.draw(e);
},
onMouseUp() {
// Stop the drawing
this.isDrawing = false;
}
}
this.lastX = e.offsetX
this.lastY = e.offsetY
// Using ES6
[this.lastX, this.lastY] = [e.offsetX, e.offsetY]
Inspired by Wes Bos' Javascript30 course