One of the fiddly things about using Html5 canvas is dragging and dropping. It’s something I needed to do a fair bit, so I thought I’d write a configurable function to do it. You can use it with Vanilla JavaScript web apps, with Apps Script HTMLService in an Add-on or as a webapp – click here to execute that, or as in the demo in this page, a Google Gadget.

The first app I’ve written using an early version of this is the Color Arranger Apps Script Add-on, but I’m expecting to be able to use this in a few more things I have in the pipeline.

You can find the code for the Apps Script version, plain JavaScript, or as a gadget here on github.

Here’s how it works.

Canvasser

This is used to manage canvas operations for a collection of shapes. It provides default mouse, dragging and animation functions and events (all of which can be customized) for dealing with the dragging, dropping and painting of shapes on a canvas. This first version only supports rectangular shapes, but I’ll be adding more stuff as I use it for more apps.

In addition to x,y co-ordinates relative to the canvas, it also supports a z level for layers (what goes in front).

The purpose is to manage all the mouse and shape coordination to generate a smooth drag and drop experience. Below is an apps script webapp using canvasser with some shapes to play around with.

demo of canvasser function

Let’s work through the example.

Initialization

It needs the element containing the canvas it’s supposed to work on.

Adding shapes

Canvasser keeps track of all the shapes plotted on it with CanvasserShape objects. A new, default shape is created like this.

The default shape template object looks like this. Each shape that is added will use these values as the default. An example is the black shape in the top left corner of the demo.

Shape parameters

Any of the above can be changed by passing an example object to the CanvasserShape constructor. Here’s the green and yellow shapes in the demo.

Events

There are a number of specific events that can be monitored. Many events can be global (apply to all shapes), or can be tailored for specific shapes. We’ll dig into that a little more later, but for now, let’s say I want to provoke a callback when the mouse enters a new shape, or exits an old one.

In this case I want to turn an element on my web page ‘block’ , to the same color as the shape I’m entering, or gray if I’m leaving.

Try on the demo moving the mouse over various shapes

Copying properties from other shapes

You may want to use one shape as the template for another. In this case, I’m creating the blue shape and copying it to make the pink shape

and then make a few minor adjustments directly

The data property

In the blue/pink example you’ll notice that the CanvasserShape is initialized with a shape property, plus a data property. The shape property describes the shape’s characteristics, but the data property is provided as a convenient container for whatever data you want to associate with a shape. This means that when you get a callback where the CanvasserShape is passed to you, any data that it carries will be accessible too.

[spacer size=”40″]

onDragEnd event

Each shape can have its own personal callback for a dragEnd (or dragStart) that can override the default dragEnd behavior. In this case we want to fill a couple of elements (defined earlier in the data property of the pink and blue shapes) with some data associated with each shape.

onDragEnd callback is called with 2 arguments.

  • shape – this is the CanvasserShape that’s being dragged
  • isOver – this is the CanvassertShape it was positioned over when it was dropped. It may be null if there was no shape in the drop position.

In this example both the pink and blue shapes now have the same customized onDragEnd event, whereas the other shapes do not. Play around with dragging the pink and blue shapes in the demo below

Placing in new position

When a shape is dropped in a new position, there are a number of positioning modes.

These have been identified so far

  • PLACE – the item is dropped where it lands, and no other shape is affected
  • SWAP – the item swaps position with the one it’s now over
  • SHUFFLE – the item is inserted in the drop position and the subsequent items are all pushed down to make room – this is not yet implemented, but is in progress

By default, items use the PLACE mode. Here’s an example of selecting the SWAP mode

Text

There is a primitive text capability, which allows you to label shapes. See the default item earlier for the properties supported

Z position of dragged items

By default a dragged items Z position will be changed when dropped to put it on the top layer. However you can configure a shape to retain its original position after being dragged as in the lemonchiffon example above, or you can specify a specific Z position.

  • Retain current Z position – dragz : cv.ENUMS.LAYERS.UNCHANGED
  • Move on top – dragz : cv.ENUMS.LAYERS.ONTOP
  • Use a specific z position – dragz : 23

Play around with the lemonchiffon and indigo shapes to see the SWAP and UNCHANGED behaviors in action.

For more like this see Google Apps Scripts Snippets
Why not join our forum,follow the blog or follow me on twitter to ensure you get updates when they are available.