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.

I lead the Chrome Developer Relations team at Google.

We want people to have the best experience possible on the web without having to install a native app or produce content in a walled garden.

Our team tries to make it easier for developers to build on the web by supporting every Chrome release, creating great content to support developers on web.dev, contributing to MDN, helping to improve browser compatibility, and some of the best developer tools like Lighthouse, Workbox, Squoosh to name just a few.

I'm trialing a newsletter, you can subscribe below (thank you!)