-
-
Save pixlpa/9396624 to your computer and use it in GitHub Desktop.
For each shape drawn into a canvas, an offscreen canvas is painted with the same shape, with the red color channel storing an ID. Shape click-testing is done by querying the color of the clicked position in the offscreen canvas. For UI with a lot of shapes (data viz for example) this is much more efficient than looping through and hit testing ba…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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').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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment