简体   繁体   中英

Referencing canvas graphics as DOM elements with jQuery

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM