Drawing draggable shapes on Canvas with CreateJS

While working for a cross platform hybrid app, I had the requirement of drawing draggable shapes on Canvas. I came across many JavaScript Canvas Libraries such as jCanvas, which suited the purpose. However, I finally settled down for CreateJS.

In this post, I will show how I created draggable shapes such as circle, rectangles and star on Canvas with EaselJS, part of CreateJS library for drawing on Canvas.

draggable shapes on canvas
Tap on Image for Full Screen demo of draggable shapes on Canvas

About CreateJS

CreateJS comes with a wide set of libraries called EaselJS (drawing on canvas), TweenJS (animating on canvas), SoundJS (playing sound with javascript) & PreloadJS (preloading assets like sounds, images). Together they are capable of powering your next cross-platform hybrid app or game built on HTML5 Canvas. These libraries are designed to work completely independently.

In this post, I will just be using EaselJS for drawing shapes and making them draggable upon mouse or touch interactions.

Creating shapes on Canvas with EaselJS

In HTML, we need to define our canvas and give it a suitable id so that we can refer it in JavaScript. Also we hook onto the body onload event to initate our work. We link up the createjs library from the createjs CDN. That is all we need to put into our HTML as most of the work will be done in JavaScript.

<script src="http://code.createjs.com/createjs-2013.12.12.min.js"></script>
<body onload="init();">
<canvas id="canvas" width="500" height="500"></canvas>
</body>
<!--html file-->

Scale Canvas to full width & height

The first thing that I will do in JavaScript init() method is to scale the canvas to occupy full width and height. This way we will make sure that our canvas is able to dynamically adjust to the screen size of user. This is done using the code below:

var canvas = document.getElementsByTagName('canvas')[0];
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//scale canvas

Note that the above code will  ensure canvas resize to full screen only once i.e. upon load of html document in clients browser. If you need to adjust canvas upon every windows resize, you may want to hook onto onresize event to execute this piece of code.

Draw Geometrical Shapes on canvas

CreateJS allows us to easily draw geomterical shapes on canvas with desired size, fill and position. In order to do that, we need to first initialize a stage object with our canvas, then we create shape objects and ask CreateJS to draw the desired shape for this shape object. Afterwards we add these shape objects to the stage and call stage.update() which will do the actual drawing in the canvas.

Below you can see JavaScript code for creating and drawing circle shape which is then added to the stage. For code used to draw other shapes, please refer to the codepen for this post.

function addCircle(x, y, r, fill) {
 var circle = new createjs.Shape();
 circle.graphics.beginFill(fill).drawCircle(0, 0, r);
 circle.x = x;
 circle.y = y;
 circle.name = "circle";
 circle.on("pressmove", drag);
 stage.addChild(circle);
}
//drawing circle and adding to stage

Making shapes draggable

As you will notice, I have registered drag function with the “pressmove” event with every shape. This will allow us to listen to the drag event on shapes and update the co-ordinates of our shape at the touch point. Since all the drawn objects are a Shape object, we use a single drag function shown below. I had to handle the square shape separately as the anchor point for square shapes is top-left.

function drag(evt) {
 // target will be the container that the event listener was added to
 if(evt.target.name == "square") {
  evt.target.x = evt.stageX - SIZE;
  evt.target.y = evt.stageY - SIZE;
 }
 else {
  evt.target.x = evt.stageX;
  evt.target.y = evt.stageY;
 }

 // make sure to redraw the stage to show the change
 stage.update();
}
//handle drag of shapes

Draggable Shapes Demo

See the Pen Drawing draggable shapes on Canvas by Kanishk Kunal on CodePen.0

Kanishk Kunal

Kanishk is a Software Engineer turned Online Entrepreneur who has created many successful apps and websites. He devotes most of his time punching his keyboard and swiping his smartphone. Follow him on Twitter @kanishkkunal

This Post Has 9 Comments

  1. Hi Kanishk Kunal,
    Thanks for you post.
    I would like to ask: how can dynamic resize shape (square) ?

    1. You need to call square.graphics.clear().beginFill(fill).drawRoundRect(0, 0, s, s, r) with new dimensions followed by stage.update() to change the shape of the square.

  2. Kanishk,

    I have achieved what you have demonstrated, however, is there a way to track the percentage two objects overlap? Here is my site http://www.witeami.com/gati.html I am trying to track the percentage of two circles overlapping. Then track all three circles overlapping.

    1. Hi Mark, It is possible to find the area overlapped by circles. You can use the circle’s center and radius to do the calculation as show here: http://mathworld.wolfram.com/Circle-CircleIntersection.html

      1. That helps a ton! Thank you.

  3. Hi Kanishk,

    Thank you for this, it was super useful! I’m wondering if you knew an easy trick to automatically reset the layout to the default position after, say, three “drags”?

    1. Hi Gaelle, you can achieve this by storing the initial center position of the shapes and then moving them back to the initial position after three drags. You can listen to the ‘pressup’ event to detect the third drag. Check out the EaselJS mouse interaction tutorial for more information: http://www.createjs.com/tutorials/Mouse%20Interaction/

  4. Have you had a look at https://konvajs.github.io/ ? Im about to do a project and thinking about using it rather than createjs.

    1. Hello Louie, I have not tried Konva, but it does look promising.

Leave a Reply

Close Menu