Skip to content

Instantly share code, notes, and snippets.

Created March 6, 2014 18:41
Show Gist options
  • Save anonymous/9396568 to your computer and use it in GitHub Desktop.
Save anonymous/9396568 to your computer and use it in GitHub Desktop.
A Pen by Andrew Benson.

Draggable Shapes

Sketch for doing hit-testing of arbitrary shapes on a canvas. Checks color of offscreen canvas, which is encoded with an ID# in the red channel. Lower right corner drags resize boxes.

A Pen by Andrew Benson on CodePen.

License.

<canvas id="cvs" width="1200px" height="800px"></canvas><div id="jim"></div>
<div id="flyover"></div>
var canvas = document.getElementById('cvs'),
c = canvas.getContext('2d'),
ocan = document.createElement("canvas"),
oc = ocan.getContext('2d');
ocan.width=canvas.width;
ocan.height=canvas.height;
var offx = canvas.offsetLeft;
var offy = canvas.offsetTop;
var lastX = 0,lastY=0;
var active = 0;
var boxes = new Array();
for(var i=1;i<60;i++){
if(i<30){
boxes[i]=new uiBox(i,Math.random()*400,Math.random()*200,Math.random()*100,Math.random()*50,randomColor());
boxes[i].draw();
}
else {
boxes[i]=new uiCircle(i,Math.random()*400+400,Math.random()*200,Math.random()*30+5,randomColor());
boxes[i].draw();
}
}
$(document).ready(function(){
$('#cvs').mousemove(function(e){
var x = e.pageX-offx;
var y = e.pageY-offy;
var act = getID(x,y);
var fly = $('#flyover'); fly.css('opacity',1.);
fly.css('top',e.pageY+5+'px');
fly.css('left',e.pageX+20+'px');
fly.text("ID:"+act);
//$('#flyover').css('opacity',0.);
});
$('#cvs').mousedown(function(e){
var x = e.pageX-offx;
var y = e.pageY-offy;
active = getID(x,y);
lastX = x;
lastY = y;
if(active>0){
if (boxes[active].isCorner(x,y)==1){
$(window).bind("mousemove",function(e){
var x = e.pageX-offx;
var y = e.pageY-offy;
if(active>0){
if(active<30){
boxes[active].w += x-lastX;
if(boxes[active].w<5) boxes[active].w = 5;
boxes[active].h += y-lastY;
if(boxes[active].h<5) boxes[active].h = 5;
}
else {
boxes[active].r += x-lastX;
if(boxes[active].r<5) boxes[active].r = 5;
}
lastX = x;
lastY = y;
oc.clearRect(0,0,1200,800);
c.clearRect(0,0,1200,800);
for(var i=1;i<60;i++){
boxes[i].draw();
}
}
});
}
else {
$(window).bind("mousemove",function(e){
var x = e.pageX-offx;
var y = e.pageY-offy;
if(active>0){
boxes[active].x+=x-lastX;
boxes[active].y+=y-lastY;
}
lastX = x;
lastY = y;
oc.clearRect(0,0,1200,800);
c.clearRect(0,0,1200,800);
for(var i=1;i<60;i++){
boxes[i].draw();
}
c.fillStyle = "#888";
});
}
}
$(window).bind('mouseup',function() {
$(this).unbind('mousemove');
active = 0;
oc.clearRect(0,0,1200,800);
c.clearRect(0,0,1200,800);
for(var i=1;i<60;i++){
boxes[i].draw();
}
});
});
});
function getID(x,y){
var p = oc.getImageData(x, y, 1, 1).data;
//use blue channel as reference to
//see if it's a fuzzy edge pixel
if(p[2]==255) return p[0];
else return 0;
}
function randomColor(){
var cc = new Array();
var r = Math.random()*255;
var g = Math.random()*255;
var b = Math.random()*255;
return ((r << 16) | (g << 8) | b).toString(16);;
}
function uiBox(id,x,y,w,h,color){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.color = color;
this.id = id;
this.draw = function(){
c.fillStyle = this.color;
oc.fillStyle = 'rgb('+this.id+',0,255)';
c.fillRect(this.x,this.y,this.w,this.h);
oc.fillRect(this.x,this.y,this.w,this.h);
}
this.isCorner = function(l,t){
var checkx = l > (this.x+this.w-10);
var checky = t > (this.y+this.h-10);
return (checkx&&checky);
}
}
function uiCircle(id,x,y,r,color){
this.x = x;
this.y = y;
this.r = r;
this.color = color;
this.id = id;
this.draw = function(){
c.fillStyle = this.color;
oc.fillStyle = 'rgb('+this.id+',0,255)';
c.beginPath();
oc.beginPath();
c.arc(this.x,this.y,this.r, 0, 2 * Math.PI, false);
oc.arc(this.x,this.y,this.r, 0, 2 * Math.PI, false);
c.closePath();
oc.closePath();
c.fill();
oc.fill();
}
this.isCorner = function(l,t){
var checkx = l > (this.x+this.r-10);
return (checkx);
}
}
#flyover {
width: 20px;
height: 10px;
border-radius: 4px;
box-shadow: -3px 3px 5px #555;
background-color: #FBFBFB;
position:absolute;
z-index:2;
top: 0px;
left: 0px;
opacity:0;
font-size:10px;
padding:5px;
transition: opacity 0.3s;
-webkit-transition: opacity 0.3s;
}
canvas {
z-index:1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment