1
votes

I have a stage and a container on a single Canvas.

Inside the the stage I add a Container which contains two rectangle shapes. I bind a function to the stagemousedown event of the stage which returns the shape under the coordinates where the event took place through getObjectUnderPoint function.

HTML:

<body onload="init();">
   <canvas id="canvas" width="300" height="200">
   </canvas>
   <button onclick="zoom()">zoom it</button>
</body>

Function which initialize the stage, container and the two rectangles:

function init() {

    stage = new createjs.Stage("canvas");
    container = new createjs.Container();
    var rect1 = new createjs.Shape();
    rect1.graphics.beginFill("#ff0000").drawRect(10, 10, 100, 100);
    container.addChild(rect1);
    var rect2 = new createjs.Shape();
    rect2.graphics.beginFill("#00ff00").drawRect(120, 10, 100, 100);
    container.addChild(rect2);
    stage.on('stagemousedown', onClick);
    stage.addChild( container );    
    stage.update();
}

The function that returns the item under the stagemousedown event:

function onClick(e) {
    alert(stage.getObjectUnderPoint(e.stageX, e.stageY));
}

This works smoothly until I put zoom: 2 CSS to body through the zoom function. Once I click on the edge of the rectangle, I am not getting the object.

function zoom(){
    document.body.style.zoom = 2;
    container.scaleX = container.scaleY = 2;

}

I read, that EaselJS doesn't work with zoomed canvases. So I put this:

container.scaleX = container.scaleY = 2;

Which works partially, because there are part of the area which is still not clickable:

enter image description here

Everything outside the black rectangle area is not triggering the stagemousedown event.

How can I be able to make this work?

NOTE: I need to use the stage.on method and not container.addEventListener

http://jsfiddle.net/vqq8dxw7/1/

EDIT: Thanks, but the zoom is something I need, because the purpose of the whole thing is to have the whole application zoomed for responsive purposes (without zooming every single html element).

So, I zoom the body, and everything is zoomed like this:

http://jsfiddle.net/vqq8dxw7/5/

2

2 Answers

2
votes

In your fiddle, you aren't updating the stage after you change the scaleX and scaleY of the container so the canvas is never redrawn with the new scale. You ARE, however, still changing the css zoom. You need only change the scale of the container and update the stage.

I've updated your fiddle to achieve the desired result.

function zoom(){
    //document.body.style.zoom = 2;
    container.scaleX = container.scaleY = 2;
    stage.update();
}
0
votes

That was the solution to my actual problem (the one after the edit). EaslJS doesn't consider the zoom CSS and the coordinates are created globally and because the zoom is translating the divs.

So I switched to transform: scale(2); and using:

body.style.top = -body.getBoundingClientRect().top + "px";
body.style.left = -body.getBoundingClientRect().left + "px";

In order to fix the position of the scaled object.

The reason I didn't think of it before is because I tried it, but I was having this issue: some items were disappearing after transform: scale(2) was applied.

Then I solved the latter with the workaround suggested in the linked stackoverflow's question, which was:

 translate3d(0px, 0px, 0px);

http://jsfiddle.net/vqq8dxw7/6/

EDIT: updated the answer because I found that it's not necessary to manually move the body, but you can do it with a "transform origin":

document.body.style.transformOrigin = "top left";

Updated jsfiddle