I had drawn some circles on a html canvas my codes looks like this:
Html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebTunings</title>
<link href="index.css" rel="stylesheet">
<script src="index.js"></script>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
<div id="controls">
<p><label>Fill: <input id="fillBox" type="checkbox" checked="checked"></label></p>
<div class="lightBorder">
<p><input type="radio" name="shape" value="circle" checked="checked">Circle</p>
</div>
<p><input id="clearCanvas" type="button" value="reset"></p>
</div>
</body>
</html>
Javascript:
var canvas,
context,
dragging = false,
dragStartLocation,
snapshot;
function getCanvasCoordinates(event) {
var x = event.clientX - canvas.getBoundingClientRect().left,
y = event.clientY - canvas.getBoundingClientRect().top;
return {x: x, y: y};
}
function takeSnapshot() {
snapshot = context.getImageData(0, 0, canvas.width, canvas.height);
}
function restoreSnapshot() {
context.putImageData(snapshot, 0, 0);
}
function drawCircle(position) {
var radius = Math.sqrt(Math.pow((dragStartLocation.x - position.x), 2) + Math.pow((dragStartLocation.y - position.y), 2));
context.beginPath();
context.arc(dragStartLocation.x, dragStartLocation.y, radius, 0, 2 * Math.PI, false);
context.fillStyle = getRndColor();
}
function draw(position) {
var fillBox = document.getElementById("fillBox"),
shape = document.querySelector('input[type="radio"][name="shape"]:checked').value;
if (shape === "circle") {
drawCircle(position);
}
if (fillBox.checked) {
context.fill();
} else {
context.stroke();
}
}
function dragStart(event) {
dragging = true;
dragStartLocation = getCanvasCoordinates(event);
takeSnapshot();
}
function drag(event) {
var position;
if (dragging === true) {
restoreSnapshot();
position = getCanvasCoordinates(event);
draw(position, "polygon");
}
}
function dragStop(event) {
dragging = false;
restoreSnapshot();
var position = getCanvasCoordinates(event);
draw(position, "polygon");
}
function getRndColor() {
var r = 255*Math.random()|0,
g = 255*Math.random()|0,
b = 255*Math.random()|0;
return 'rgb(' + r + ',' + g + ',' + b + ')';
}
function eraseCanvas(){
context.clearRect(0, 0, canvas.width, canvas.height);
}
function init() {
canvas = document.getElementById("canvas");
context = canvas.getContext('2d');
context.strokeStyle = 'green';
context.lineWidth = 4;
context.lineCap = 'round';
clearCanvas = document.getElementById("clearCanvas");
canvas.addEventListener('mousedown', dragStart, false);
canvas.addEventListener('mousemove', drag, false);
canvas.addEventListener('mouseup', dragStop, false);
clearCanvas.addEventListener("click", eraseCanvas, false);
}
window.addEventListener('load', init, false);
Now what i wanted to do is whenever i draw multiple circles i wanted to select one random circle and drag it to another place on the canvas, applicable for each of the circles. I want to use only html5
and javascript
no other third party libraries. Is there any way to do this ?? any help would be great......
I had drawn some circles on a html canvas my codes looks like this:
Html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebTunings</title>
<link href="index.css" rel="stylesheet">
<script src="index.js"></script>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
<div id="controls">
<p><label>Fill: <input id="fillBox" type="checkbox" checked="checked"></label></p>
<div class="lightBorder">
<p><input type="radio" name="shape" value="circle" checked="checked">Circle</p>
</div>
<p><input id="clearCanvas" type="button" value="reset"></p>
</div>
</body>
</html>
Javascript:
var canvas,
context,
dragging = false,
dragStartLocation,
snapshot;
function getCanvasCoordinates(event) {
var x = event.clientX - canvas.getBoundingClientRect().left,
y = event.clientY - canvas.getBoundingClientRect().top;
return {x: x, y: y};
}
function takeSnapshot() {
snapshot = context.getImageData(0, 0, canvas.width, canvas.height);
}
function restoreSnapshot() {
context.putImageData(snapshot, 0, 0);
}
function drawCircle(position) {
var radius = Math.sqrt(Math.pow((dragStartLocation.x - position.x), 2) + Math.pow((dragStartLocation.y - position.y), 2));
context.beginPath();
context.arc(dragStartLocation.x, dragStartLocation.y, radius, 0, 2 * Math.PI, false);
context.fillStyle = getRndColor();
}
function draw(position) {
var fillBox = document.getElementById("fillBox"),
shape = document.querySelector('input[type="radio"][name="shape"]:checked').value;
if (shape === "circle") {
drawCircle(position);
}
if (fillBox.checked) {
context.fill();
} else {
context.stroke();
}
}
function dragStart(event) {
dragging = true;
dragStartLocation = getCanvasCoordinates(event);
takeSnapshot();
}
function drag(event) {
var position;
if (dragging === true) {
restoreSnapshot();
position = getCanvasCoordinates(event);
draw(position, "polygon");
}
}
function dragStop(event) {
dragging = false;
restoreSnapshot();
var position = getCanvasCoordinates(event);
draw(position, "polygon");
}
function getRndColor() {
var r = 255*Math.random()|0,
g = 255*Math.random()|0,
b = 255*Math.random()|0;
return 'rgb(' + r + ',' + g + ',' + b + ')';
}
function eraseCanvas(){
context.clearRect(0, 0, canvas.width, canvas.height);
}
function init() {
canvas = document.getElementById("canvas");
context = canvas.getContext('2d');
context.strokeStyle = 'green';
context.lineWidth = 4;
context.lineCap = 'round';
clearCanvas = document.getElementById("clearCanvas");
canvas.addEventListener('mousedown', dragStart, false);
canvas.addEventListener('mousemove', drag, false);
canvas.addEventListener('mouseup', dragStop, false);
clearCanvas.addEventListener("click", eraseCanvas, false);
}
window.addEventListener('load', init, false);
Now what i wanted to do is whenever i draw multiple circles i wanted to select one random circle and drag it to another place on the canvas, applicable for each of the circles. I want to use only html5
and javascript
no other third party libraries. Is there any way to do this ?? any help would be great......
- can you give jsfiddle link?? – AL-zami Commented Feb 2, 2015 at 19:15
- this is the jsfiddle link – Proloy Commented Feb 2, 2015 at 19:32
1 Answer
Reset to default 25Canvas does not "remember" where it drew your circles or rectangles, so you must do the remembering. This is typically done by defining each circle or rect in a javascript object and saving all those shapes in a shapes[] array.
// an array of objects that define different shapes
var shapes=[];
// define 2 rectangles
shapes.push({x:10,y:100,width:30,height:30,fill:"#444444",isDragging:false});
shapes.push({x:80,y:100,width:30,height:30,fill:"#ff550d",isDragging:false});
// define 2 circles
shapes.push({x:150,y:100,r:10,fill:"#800080",isDragging:false});
shapes.push({x:200,y:100,r:10,fill:"#0c64e8",isDragging:false});
Then you can listen for mouse events in javascript. When the browser issues a mouse event you can call a function in response. This is how to tell the browser you want to listen to mouse events:
// listen for mouse events
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;
canvas.onmousemove = myMove;
You can use the mouse event functions (myDown, myUp, myMove) to do your dragging.
Upon a mousedown event (handled by the myDown function), you test each shape to see if the mouse is inside one of the shapes in your array. If the mouse is inside 1+ shapes, set an
isDragging
flag on those 1+ shapes and also set adragok
flag to indicate that you need to track the mouse for dragging purposes.Upon a mousemove event (handled by the myMove function), you move any shape that is being dragged by the distance the mouse has dragged since the previous mousemove.
Upon a mouseup event (handled by the myUp function), you stop the dragging operation by clearing the dragok flag.
Here's annotated example code and a Demo:
// get canvas related references
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var BB=canvas.getBoundingClientRect();
var offsetX=BB.left;
var offsetY=BB.top;
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
// drag related variables
var dragok = false;
var startX;
var startY;
// an array of objects that define different shapes
var shapes=[];
// define 2 rectangles
shapes.push({x:10,y:100,width:30,height:30,fill:"#444444",isDragging:false});
shapes.push({x:80,y:100,width:30,height:30,fill:"#ff550d",isDragging:false});
// define 2 circles
shapes.push({x:150,y:100,r:10,fill:"#800080",isDragging:false});
shapes.push({x:200,y:100,r:10,fill:"#0c64e8",isDragging:false});
// listen for mouse events
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;
canvas.onmousemove = myMove;
// call to draw the scene
draw();
// draw a single rect
function rect(r) {
ctx.fillStyle=r.fill;
ctx.fillRect(r.x,r.y,r.width,r.height);
}
// draw a single rect
function circle(c) {
ctx.fillStyle=c.fill;
ctx.beginPath();
ctx.arc(c.x,c.y,c.r,0,Math.PI*2);
ctx.closePath();
ctx.fill();
}
// clear the canvas
function clear() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
// redraw the scene
function draw() {
clear();
// redraw each shape in the shapes[] array
for(var i=0;i<shapes.length;i++){
// decide if the shape is a rect or circle
// (it's a rect if it has a width property)
if(shapes[i].width){
rect(shapes[i]);
}else{
circle(shapes[i]);
};
}
}
// handle mousedown events
function myDown(e){
// tell the browser we're handling this mouse event
e.preventDefault();
e.stopPropagation();
// get the current mouse position
var mx=parseInt(e.clientX-offsetX);
var my=parseInt(e.clientY-offsetY);
// test each shape to see if mouse is inside
dragok=false;
for(var i=0;i<shapes.length;i++){
var s=shapes[i];
// decide if the shape is a rect or circle
if(s.width){
// test if the mouse is inside this rect
if(mx>s.x && mx<s.x+s.width && my>s.y && my<s.y+s.height){
// if yes, set that rects isDragging=true
dragok=true;
s.isDragging=true;
}
}else{
var dx=s.x-mx;
var dy=s.y-my;
// test if the mouse is inside this circle
if(dx*dx+dy*dy<s.r*s.r){
dragok=true;
s.isDragging=true;
}
}
}
// save the current mouse position
startX=mx;
startY=my;
}
// handle mouseup events
function myUp(e){
// tell the browser we're handling this mouse event
e.preventDefault();
e.stopPropagation();
// clear all the dragging flags
dragok = false;
for(var i=0;i<shapes.length;i++){
shapes[i].isDragging=false;
}
}
// handle mouse moves
function myMove(e){
// if we're dragging anything...
if (dragok){
// tell the browser we're handling this mouse event
e.preventDefault();
e.stopPropagation();
// get the current mouse position
var mx=parseInt(e.clientX-offsetX);
var my=parseInt(e.clientY-offsetY);
// calculate the distance the mouse has moved
// since the last mousemove
var dx=mx-startX;
var dy=my-startY;
// move each rect that isDragging
// by the distance the mouse has moved
// since the last mousemove
for(var i=0;i<shapes.length;i++){
var s=shapes[i];
if(s.isDragging){
s.x+=dx;
s.y+=dy;
}
}
// redraw the scene with the new rect positions
draw();
// reset the starting mouse position for the next mousemove
startX=mx;
startY=my;
}
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<h4>Drag one or more of the shapes</h4>
<canvas id="canvas" width=300 height=300></canvas>