Kineticjs Drag & Drop

KineticJS inherently supports dragging of elements, but what if you need “Drop” as well, sure you may drop anything anywhere on the stage but most of the times we want to be able to drop stuff in a pre-defined position and then apply some transformation. This is an example how we can achieve something like this easily.

Here is a codepen DEMO:

See the Pen Kinetic JS drag n drop by Michael Dobekidis (@netgfx) on CodePen.

So let us break it down and see how it is constructed.

First we declare our HTML

<div id="container"></div>

Next we create the stage and the additional elements in KineticJS declaration

var stage;
var initCoords = {x:0, y:0};

  function writeMessage(message) {
      stage = new Kinetic.Stage({
        container: 'container',
        width: 1024,
        height: 800
      var layer = new Kinetic.Layer();

      var text = new Kinetic.Text({
        x: 10,
        y: 10,
        fontFamily: 'Calibri',
        fontSize: 24,
        text: 'Drag the blue rectangle inside (or outside) of the yellow one and Drop it',
        fill: 'white'
      var box = new Kinetic.Rect({
        x: 589,
        y: 100,
        offset: [50, 25],
        width: 100,
        height: 50,
        fill: '#00D2FF',
        stroke: 'black',
        strokeWidth: 4,
        draggable: true
      var boxTarget = new Kinetic.Rect({
        x: 100,
        y: 100,
        offset: [50, 25],
        width: 200,
        height: 100,
        fill: '#fec72c',
        stroke: 'white',
        strokeWidth: 4,
        draggable: false,
        name: "droppable"

      // write out drag and drop events
      box.on('dragstart', function(e) {
        initCoords = {,};
      box.on('dragend', function(e) {


Here we have the stage the main layer, a handy function to display messages (this is only needed for the display purposes of this example), and the draggable and droppable rectangles. Also at the end of the “ready” function we also declare the event listeners for the drag-start and drag-end.

Now lets see what these functions really do

function onDragEnd(e) {
  var droppableTargets  = stage.find('.droppable');
  var draggable =;
  for(var i=0;i<droppableTargets.length;i++){
    // we use the fit calculation
    var result = doObjectsFit(draggable, droppableTargets[i]);
    if(result === true) {
      var targetW = droppableTargets[i].width();
      var targetH = droppableTargets[i].height();
      var targetX = droppableTargets[i].x() + (targetW/2 - draggable.width()/2);
      var targetY = droppableTargets[i].y() + (targetH/2 - draggable.height()/2);
      return true;
    else {
// we return the object to its initial position
      var tween = new Kinetic.Tween({
        node: draggable,
        duration: 0.4,
        x: initCoords.x,
        y: initCoords.y

Now the drag start doesn’t really do anything apart from letting us know when the object is actually moving. On the other hand the function that is fired when we release the object is quite tricky, what this function really do is to “test” if the two objects (rectangles) are overlapping, touching, or fit one another, these are the three conditions that we might declare as we have here by running the doObjectsFit function which receives the two objects as paramaters and analyses them and simply returns a boolean value of true/false.
And according to that value we can apply any number of transformations to the objects.

Here are the functions that do the testing

function doObjectsTouch(a, b) { // a and b are your objects
   return !(
    ((a.y() + a.height()) < (b.y())) ||
    (a.y() > (b.y() + b.height())) ||
    ((a.x() + a.width()) < b.x()) ||
    (a.x() > (b.x() + b.width()))

function doObjectsFit(a, b) { // a and b are your objects
   if( (a.y()) > (b.y()) &&
       (a.y() + a.height()) <= (b.y() + b.height()) &&
       (a.x()) > (b.x()) &&
       (a.x() + a.width()) < (b.x()+b.width())
     return true;

function doObjectsIntersect(a, b) { // a and b are your objects
   if( (a.y()) > (b.y()+b.height()/2) &&
       (a.y() + a.height()) <= (b.y() + b.height()) &&
       (a.x()) > (b.x()) &&
       (a.x() + a.width()) < (b.x()+b.width())
     return true;

I hope you found this tutorial useful. If you liked this, drop me a line below.


Tagged , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *