Using HTML Canvas with Vue JS

Scott Cook
3 min readOct 29, 2019

--

Vue is a very powerful javascript framework that works by taking control of the DOM, or what the user sees on the webpage. However, there’s some cases where HTML features, such as the Canvas element, that have their own API. This means that control of the Canvas will not work out of the box with Vue, and there’s a little bit of wiring that needs to be done to ensure Vue has control of the Canvas API. Let’s work through an example.

Here’s an example from my project, watermarks.io. Try it out.

demo from watermarks.io using Vue to control Canvas API

Some Background:

One important thing to note is that the HTML Canvas API is clearly defined, but rather rudimentary. It is not “Photoshop” out of the box. For example, the Canvas API does not have any notion of “history” (for the most part). Once an element is added to the canvas, that element cannot be accessed directly through the through the API… rather, you need to keep a state outside of the canvas and redraw a new element if you want to make changes to that.

The Example:

Let’s add a rectangle to an HTML Canvas that has two buttons that Vue uses to increase and decrease the rectangles width.

First let’s make the Canvas …

A canvas element will need to be present and visible within the HTML. In my case I have a <canvas id="c"></canvas> in the DOM that I grab in JS. The next line stores this canvas’ context into a variable. This context is used to add text, shapes, images, and other objects to the canvas.

Once the context is defined, you can draw an rectangle:

var c = document.getElementById("c");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.rect(20, 20, 150, 100);
ctx.stroke();

Now lets hook it into Vue…

The trick to allowing Vue to manage “state” of the canvas is by storing size, color, and other attributes for canvas elements as Vue data. As those values change, you trigger Vue to redraw the context with the Vue data as inputs.

To do this you need to make the canvas context accessible by all Vue methods by setting the canvas context to a Vue data variable:

mounted() {
var c = document.getElementById("c");
var ctx = c.getContext("2d");
this.vueCanvas = ctx;
},

This can be accomplished by initializing the canvas and context in the mounted()lifecycle hook. This function fires right after Vue and DOM are fully initialized. Now this.vueCanvas can easily be called in other methods.

Let’s add methods to add and resize a rectangle using@click :

This should be business a usual if you’re familiar with Vue. These three methods are tied to three buttons which fire v-on:click … Keep in mind that each time the drawRect() function is called, the canvas needs to be cleared in order for the new canvas element to be drawn.

  drawRect() {
// clear canvas
this.vueCanvas.clearRect(0, 0, 400, 200);

// draw rect
this.vueCanvas.beginPath();
this.vueCanvas.rect(20, 20, this.rectWidth, 100);
this.vueCanvas.stroke();
},
addWidth() {
this.rectWidth += 10
this.drawRect()
},
subWidth() {
this.rectWidth -= 10
this.drawRect()
}
}

Let’s put it together:

Here’s a working example you can play around with

Bonus

There are quite a few javascript libraries that allow more “out of the box” control of the canvas:

These libraries make it much easier to declare an element on the canvas and simply reference the element to change width/color/other attributes. Regardless of if you use a basic approach or canvas library, you will still need to assign the canvas to a data() property in the mounted() hook so it can be addressed throughout your application.

Happy designing!

--

--