Drag-and-drop between canvas tags
Written by Richard Heyes, on 17th January 2013
Update:
This example has been changed to use "Click to pick up, click to put down"
This makes dragging much more
comfortable and avoids any selection peculiarities.
This is a demo that shows you how you can drag an image from one
canvas
to another. The canvas
tags have
a css
border so that they can be clearly seen and the image is the RGraph logo (in the CodePen example a
data:
string is used instead of a standard image URL. As with most canvas
operations the
code is verbose - but most of it is concerned with dragging the image around the canvas
.
How it works
Because canvas
is effectively a blank piece of paper on your page on to which you can draw, the canvas
tags need to be
completely redrawn when moving the image. As a result, it means that the coordinates for the images need to be calculated
from the mouse coordinates. The switch from canvas
to canvas
is done by having each canvas
update a "state" variable
that dictates which canvas
the image should be drawn on.
The JavaScript code
<script> // Everything starts when the page has finished loading window.onload = function () { var canvas1 = document.getElementById("cvs1"); var canvas2 = document.getElementById("cvs2"); var context1 = canvas1.getContext('2d'); var context2 = canvas2.getContext('2d'); var imageXY = {x: 5, y: 5}; // // This draws the image to the canvas // function draw () { // Clear both canvas tags first context1.clearRect(0,0,canvas1.width,canvas1.height); context2.clearRect(0,0,canvas2.width,canvas2.height); // Draw a red rectangle around the image if (state && state.dragging) { state.canvas.getContext('2d').strokeStyle = 'red'; state.canvas.getContext('2d').strokeRect(imageXY.x - 2.5, imageXY.y - 2.5, state.image.width + 5, state.image.height + 5); } // Now draw the image state.canvas.getContext('2d').drawImage(state.image, imageXY.x, imageXY.y); } canvas2.onclick = canvas1.onclick = function (e) { if (state && state.dragging) { state.dragging = false; draw(); return; } var mouseXY = RGraph.getMouseXY(e); state.canvas = e.target; if ( mouseXY[0] > imageXY.x && mouseXY[0] < (imageXY.x + state.image.width) && mouseXY[1] > imageXY.y && mouseXY[1] < (imageXY.y + state.image.height)) { state.dragging = true; state.originalMouseX = mouseXY[0]; state.originalMouseY = mouseXY[1]; state.offsetX = mouseXY[0] - imageXY.x; state.offsetY = mouseXY[1] - imageXY.y; } } canvas1.onmousemove = canvas2.onmousemove = function (e) { if (state.dragging) { state.canvas = e.target; var mouseXY = RGraph.getMouseXY(e); // Work how far the mouse has moved since the mousedon event was triggered var diffX = mouseXY[0] - state.originalMouseX; var diffY = mouseXY[1] - state.originalMouseY; imageXY.x = state.originalMouseX + diffX - state.offsetX; imageXY.y = state.originalMouseY + diffY - state.offsetY; draw(); e.stopPropagation(); } } // // Load the image on canvas1 initially and set the state up with some defaults // state = {} state.dragging = false; state.canvas = document.getElementById("cvs1"); state.image = new Image(); state.image.src = 'https://www.rgraph.net/images/logo.png'; state.offsetX = 0; state.offsetY = 0; state.image.onload = function () { draw(); } } </script>