Drag-and-drop between canvas tags
Written by Richard Heyes, RGraph author, on 17th January 2013Introduction
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 a smalle cartoon graphic. 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 HTML and JavaScript code
<script src="https://www.rgraph.net/libraries/RGraph.common.core.js"></script>
<div style="text-align: center">
<canvas id="cvs1" width="200" height="200" style="border:1px solid gray"></canvas>
<canvas id="cvs2" width="200" height="200" style="border:1px solid gray; margin-left: 30px"></canvas>
</div>
<script>
// Everything lives inside this anonymous function
(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/alex.png';
state.image.width = 48;
state.image.height = 48;
state.offsetX = 0;
state.offsetY = 0;
state.image.onload = function ()
{
draw();
}
})();
</script>