Is it possible to reference graphics drawn on an HTML5 canvas element with jQuery? Here's a function I wrote for EaselJS that iterates through an object containing arrays of vector coordinates:
function newShape(obj,shape,coords){
obj.graphics.beginFill('green');
obj.alpha = 0.05;
for (var i=0; i<coords[shape].length; i+=2) {
var arr = coords[shape].slice(i,i+2);
obj.graphics.lineTo(arr[0],arr[1]);
}
obj.graphics.closePath();
obj.graphics.endFill();
stage.addChild(obj);
}
The coords object looks something like this with 100s of points:
var coords = {};
coords['0'] = [214,266,214,291,194,291];
coords['1'] = [243,1,254,2,278,9,290,14];
coords['2'] = [109,112,116,114,129,117];
And the stage:
canvas = document.getElementById("canvas");
stage = new createjs.Stage(canvas);
shape1 = new createjs.Shape();
shape2 = new createjs.Shape();
shape3 = new createjs.Shape();
newShape(shape1,'shape1',coords);
newShape(shape2,'shape2',coords);
newShape(shape3,'shape3',coords);
I can add listeners to the rendered shape for click/touch events, however I'd like to have the ability to reference each graphic as a DOM element for use with plugins like Bootstrap Popover and niceScroll eg.. $(shape1).popover('show');
. I've been actively working on a solution with no success, any help would be much appreciated!
Option 1 :
From Shmiddty's post, a programmatic approach to referencing with 2d context:
function Shape(can) {
this.x = 0;
this.y = 0;
this.width = 0;
this.height = 0;
this.fill = "rgba(0,0,0,0)";
this.parent = can;
this.draw = function(ctx) {
if (!$(me.parent).is(':visible')) return;
var parts = me.fill.split(',');
parts[3] = $(me.parent).css("opacity") + ')';
me.fill = parts.join(',');
ctx.fillStyle = me.fill;
ctx.fillRect(me.x, me.y, me.width, me.height);
};
var me = this;
}
(function() {
var can = $("#sandbox")[0],
ctx = can.getContext('2d'),
wid = can.width,
hei = can.height,
sha = new Shape($('<div id="box"/>').appendTo('body'));
sha.x = 0;
sha.y = 0;
sha.width = 50;
sha.height = 50;
sha.offsetWidth = 50;
sha.offsetHeight = 50;
sha.fill = "rgba(000,111,222,1)";
(function draw(){
ctx.clearRect(0,0,wid,hei);
sha.draw(ctx);
webkitRequestAnimationFrame(draw);
})();
$(can).click(function(){
$(sha.parent).fadeToggle();
});
$('#box').click(function(){
$(this).fadeToggle();
});
})();
Option 2 :
I was able to track x,y coords from click and touch events by applying CSS to a hidden DOM element.
Calling a bootstrap popover :
$("#canvas").click(function(e) {
var x = e.pageX;
var y = e.pageY;
if ($.inArray(x, coords['shape1']) !== -1 || $.inArray(y, coords['shape1']) !== -1){
$("#myObj").css({'position':'absolute','top':y,'left':x}).popover({
trigger: 'click',
placement:'top',
}).popover('show');
}
});
stage.update();
HTML:
<canvas id="canvas" width="375" height="322"></canvas>
<span class="myObj" data-content="lorem ipsum content" data-original-title="pop-title"></span>