Using HTML5 Canvas with Drag and Drop (setDragImage)

Using HTML5 Canvas with Drag and Drop (setDragImage)

I know a lot of people complain about Drag and Drop (DnD), but it is not all that bad. At least we have a platform to work off for the future.

We have recently seen a lot of improvements to Gmail which now includes additional support for Dragging in to Gmail to upload your docs and files, and also dragging attachments out of Gmail to the user file system. I like both of these pieces of functionality, they are subtle but introduce

One thing that I see from the jQuery UI world is that it makes DnD very easy to implement but also very pretty. Whilst HTML5 DnD has support for attaching any arbitrary element to the drag operation, in practice I have never seen a browser implement it, so we are left to our own devices on what we want to show to the user during a drag operation.

I have produced a very (rough) sample – http://html5samples.appspot.com/canvasToDrag.html. There is still a lot of work for me to do with my sample (it needs to be a lot prettier). It is very simple to use, select the negatives that you wish to “develop” and drag them into the development area. You will see that there is a “fan” effect on the drag icon. I must warn that this only works on Webkit browsers (so Chrome and Safari – actually, the drop doesn’t work in Safari yet)

This is all enabled through DataURI’s. I take the selected images and add them to the canvas (adding a little rotation and scaling for effect). Once the canvas is completed I simply call .toDataURL() on the canvas element and add it to a temporary image element. This image element is then used as in the call to the setDragImage method

// Code inside the dragStart event.

var uris = []; // A list of img uris, so I know what to display after the drag

var img = document.createElement("img");
img.src = canvas.toDataURL();

e.dataTransfer.setData("text/plain", "Text to drag");
e.dataTransfer.setData("text/uri-list", uris.join("\n"));
e.dataTransfer.setDragImage(img, 128,128);

It is pretty simple, and can allow you to do some nice effects. Things that I can’t do in HTML5 Drag and Drop is animate the element being dragged. I would love to be able animate the canvas as the user drags the elements around the screen, maybe adding a bit of inertia to the photographs as they are dragged around.