The HTML canvas is part of the HTML specification that allows developers to easily add graphics and interactivity to their apps.
In the HTML canvas, you can add images, text, and shapes with different colors, fills, and gradients. It is supported by almost all recent browsers.
To add something to a canvas, you first add a
canvas element to your page. Then, you can add lines to your canvas in the shape that you want.
For example, to add a line and a circle to your
canvas element, in your HTML file you do the following:
<canvas id="canvas" width="200" height="100" style="border:2px solid #000000;"> </canvas>
If you want to add anything more complex, it will be difficult to do.
Therefore, the Konva library abstracts the hard work of adding items to the canvas. It allows you to add many more shapes by simply writing a few lines of code.
You can also allow users to move and transform your shapes easily, which you would have to write yourself if you wanted to do it in the HTML Canvas API.
In this piece, Konva will be combined with Angular to create a whiteboard where the user can add circles, rectangles, lines, and text, and move them and transform them within the whiteboard.
How it works: Konva creates a stage and a layer in the stage which will allow you to add the lines, shapes, and text that you want.
To start, we create an Angular app by running
ng new whiteboard-app. Be sure to include the routing module when asked.
I’m assuming that you have the Angular CLI installed. If not, run
npm i -g @angular/cli.
After that, we need to install the Konva library and Angular Material, which will allow us to manipulate the canvas and make our UI look pretty without a lot of effort.
To do this, run
npm i konva @angular/material.
Then, we need to create Angular services to abstract some of the repetitive logic by running
ng g service shape and
ng g service textNode.
The logic for generating shapes and text will be placed in these files.
We also need to create a page for the whiteboard. Run
ng g component whiteboardPage to make the component.
To make sure that we can see the page when we go to http://localhost:4200/, follow the instructions below.
app.module.js, replace what was generated with:
shape.service.ts, add the following:
Konva is available as an ES6 module, so we can import it.
Also, TypeScript definitions are built into the library, so autocomplete is available and they are correct (for the most part).
The three functions above will return line, circle, and rectangle shapes respectively, with pre-filled colors, strokes, and dimensions.
However, they can easily be changed to dynamic ones by adding parameters to the functions and setting the values in the object.
As we want to be able to move them, we set
true for circle and rectangle. For a line, we only allow dragging in
brush mode as we also use the line for creating the erase feature later.
text-node.service.ts, enter the following code:
The code above will return the editable text box as shown in the Konva documentation, along with the
transformer object which allows you to transform the text.
Now that we have the code to generate all the elements, we can build the UI in the
whiteboard-page.component.ts, replace the existing code with:
whiteboard-page.component.html, replace what is there with:
The two pieces of code above will highlight the button when it is clicked with the
setSelection function. The
setSelection function will set the dictionary which sets the color according to whether the button is clicked or not.
addShape function will add the shape according to which button is clicked. It will call the service functions according to the shapes, which will return the Konva object for the shape.
This will be added to the layer object, which has already been added to the stage. The transformer object is attached to the shape objects at this time as well so you can change the size of the objects on screen.
this.layer.draw() is called which will redraw the canvas so you get the latest items displayed in the canvas.
To make the eraser for the line, it just adds another line (which is always white), on top of the existing line. The line will not be in
brush mode so it will be white when created.
If we want undo functionality, we have to track the shapes and transformer objects that are added. To do this, we put them in the
shapes array and the
transformers array respectively after we add them.
Then, when the undo button is clicked, this is called:
undo function, the
transformers for the shape are detached, so the transform handles for the removed shapes will go away. Then, we called
remove() on the removed shape and redraw. We no longer get the shape and the handle.