Click here to Skip to main content
15,888,160 members
Articles / Web Development / HTML5
Tip/Trick

How to Create a Simple Drawing App using HTML 5 Canvas [fabricJS]?

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
19 Dec 2015CPOL2 min read 27.5K   6  
Steps to create a simple drawing app using HTML5 Canvas

Introduction

This tip explains simple steps to build a simple drawing app using pure JavaScript and HTML5 Canvas. It is also useful for all who want to learn or integrate pure JavaScript based drawing app.

HTML5 Canvas?

The HTML5 <canvas> element is used to draw graphics, on the fly, via scripting (usually JavaScript). The <canvas> element is only a container for graphics. You must use a script to actually draw the graphics.

Canvas has several methods for drawing paths, boxes, circles, text, and adding images. So, in this tip, I've used FabricJS as external canvas library and written JS functions to handle different features.

Create Your Drawing App

Let's target the below features in your drawing app:

  1. Drawing a rectangle
  2. Drawing a circle
  3. Drawing an image
  4. Enable and disable drawing
  5. Enable and disable pan
  6. Zoom in
  7. Zoom out
  8. Reset zoom

And you'll need the below tools:

  1. A HTML file
  2. A JavaScript file
  3. A canvas library - Fabric.js

STEP 1

Create the below files in your app directory:

  1. index.html
  2. main.js [or any file name]

STEP 2

Import FabricJS library

STEP 3

Import an image

App structure should look like below:

DrawingApp
  • index.html
  • main.js
  • myimage.jpg
  • fabric.js

Canvas and FabricJS

Go through the below links to understand more about HTML 5 canvas and FabricJS library:

Write Code

STEP 1

Load your image on canvas:

JavaScript
 var src = 'your_image_path';
 var canvas = new fabric.Canvas('canvas', {
                isDrawingMode: false
              });
              
fabric.Image.fromURL(src, function (oImg) {
                canvas.add(oImg);
            });

STEP 2

Add drawing functions to draw objects:

Draw Solid Circle

JavaScript
var onSolidCircle = function () {
            canvas.add(new fabric.Circle({ radius: 30, fill: '#f55', top: 150, left: 150 }));
        }

Draw Solid Rectangle

JavaScript
var rect = new fabric.Rect({
               top: 100,
               left: 100,
               width: 60,
               height: 70,
               fill: '',
               selection: false,
               fill: '#f55'
           });

           canvas.add(rect);

STEP 3

Start and Stop Drawing.

We need two functions which allow us to notify canvas when to start and when to stop drawing.

JavaScript
var onStartDrawing = function () {
           canvas.isDrawingMode = true;
       }

var onStopDrawing = function () {
           canvas.isDrawingMode = false;
      }

STEP 4

Add zoomin and zoomout functions.

Zoom-in and zoom-out are now a days a very basic feature in any drawing tool on any platform. Below functions will let the objects and canvas to scale to required scale factor.

Canvas needs two variables to control zooming:

JavaScript
var canvasScale = 1;
var SCALE_FACTOR = 1.2;

Zoom-in

JavaScript
var onZoomIn = function () {
            // TODO limit the max canvas zoom in

            canvasScale = canvasScale * SCALE_FACTOR;

            canvas.setHeight(canvas.getHeight() * SCALE_FACTOR);
            canvas.setWidth(canvas.getWidth() * SCALE_FACTOR);

            var objects = canvas.getObjects();
            for (var i in objects) {
                var scaleX = objects[i].scaleX;
                var scaleY = objects[i].scaleY;
                var left = objects[i].left;
                var top = objects[i].top;

                var tempScaleX = scaleX * SCALE_FACTOR;
                var tempScaleY = scaleY * SCALE_FACTOR;
                var tempLeft = left * SCALE_FACTOR;
                var tempTop = top * SCALE_FACTOR;

                objects[i].scaleX = tempScaleX;
                objects[i].scaleY = tempScaleY;
                objects[i].left = tempLeft;
                objects[i].top = tempTop;

                objects[i].setCoords();
            }

            canvas.renderAll();
        }

Zoom-out

JavaScript
var onZoomOut = function () {
           canvasScale = canvasScale / SCALE_FACTOR;

           canvas.setHeight(canvas.getHeight() * (1 / SCALE_FACTOR));
           canvas.setWidth(canvas.getWidth() * (1 / SCALE_FACTOR));

           var objects = canvas.getObjects();
           for (var i in objects) {
               var scaleX = objects[i].scaleX;
               var scaleY = objects[i].scaleY;
               var left = objects[i].left;
               var top = objects[i].top;

               var tempScaleX = scaleX * (1 / SCALE_FACTOR);
               var tempScaleY = scaleY * (1 / SCALE_FACTOR);
               var tempLeft = left * (1 / SCALE_FACTOR);
               var tempTop = top * (1 / SCALE_FACTOR);

               objects[i].scaleX = tempScaleX;
               objects[i].scaleY = tempScaleY;
               objects[i].left = tempLeft;
               objects[i].top = tempTop;

               objects[i].setCoords();
           }

           canvas.renderAll();
       }

Reset zoom

This function will bring all the objects to their respective original scale factors:

JavaScript
var onResetZoom = function () {

           canvas.setHeight(canvas.getHeight() * (1 / canvasScale));
           canvas.setWidth(canvas.getWidth() * (1 / canvasScale));

           var objects = canvas.getObjects();
           for (var i in objects) {
               var scaleX = objects[i].scaleX;
               var scaleY = objects[i].scaleY;
               var left = objects[i].left;
               var top = objects[i].top;

               var tempScaleX = scaleX * (1 / canvasScale);
               var tempScaleY = scaleY * (1 / canvasScale);
               var tempLeft = left * (1 / canvasScale);
               var tempTop = top * (1 / canvasScale);

               objects[i].scaleX = tempScaleX;
               objects[i].scaleY = tempScaleY;
               objects[i].left = tempLeft;
               objects[i].top = tempTop;

               objects[i].setCoords();
           }

           canvas.renderAll();

           canvasScale = 1;
       }

All the above codes are wrapped in the below github link:

Just download and play around.

This application would give an idea about building a simple and powerful drawing app using HTML 5 canvas. FabricJs is one of the most powerful canvas JS library which gives you an opportunity to build a browser also a touch based drawing application.

Few of the components have been used in this app:

  1. Drawing a rectangle
  2. Drawing a circle
  3. Drawing an image
  4. Enable and disable drawing
  5. Enable and disable pan
  6. Zoom in
  7. Zoom out
  8. Reset zoom

References

  1. http://fabricjs.com/
  2. http://fabricjs.com/events/
  3. http://fabricjs.com/demos/

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
India India
Technology leader with over 10 years of experience and excellent track record of building great products while enabling others to perform their roles more effectively. Having multifaceted technical career with many innovations and success stories. Well recognized for strong leadership and project management abilities while leading cross-functional teams in fast-paced and competitive environments.

I have commendable experience in technologies like Mobile App Development[Native & Hybrid], Android, iOS, Windows Phone, AWS S3/cognito/lambd, golang, C, VC++, Python, C# MVC, ASP.NET, JAVA, J2EE, Spring, SQL Server, MySQL, Oracle etc.

Also fully loaded with client side technologies like OO Java Script, jQuery, NodeJS, KendoUI, Sencha Touch and many more.

Experience in MVC, MVVM, MVP design patterns.

TECH BLOGS:
-----------------------------------------------------------------------------------------------------

https://github.com/swagatblog
https://swagatblog.wordpress.com/
https://hybridmobileappblog.wordpress.com/
http://www.codeproject.com/Members/swagatblog

LINKED-IN Group
-----------------------------------------------------------------------------------------------------
https://www.linkedin.com/groups/5107980

Comments and Discussions

 
-- There are no messages in this forum --