Dealing with webkit-transform CSS property

39 views
Skip to first unread message

Ryan Jarvis

unread,
Jul 11, 2013, 10:17:33 AM7/11/13
to caa...@googlegroups.com
Hi,

Currently I have my canvas in a div like so:
<div style="width: 1200px; height: 800px;">
    <canvas id="CAATCanvas" width="1200px" height="800px" style="width: 1200px; height: 800px;"></canvas>
</div>

and everything works fine.  However, if I add the '-webkit-transform' property to my div like so:

<div style="width: 1200px; height: 800px; -webkit-transform: scale(0.5);">
    <canvas id="CAATCanvas" width="1200px" height="800px" style="width: 1200px; height: 800px;"></canvas>
</div>

the graphics render fine but the hit detection does not.  If I try to click on an Actor, it won't register as CAAT thinks it is elsewhere on the screen (even though it is drawn in the correct place).

How can I get the hit detection to scale as well?  Thanks.

hyperandroid

unread,
Jul 11, 2013, 10:20:50 AM7/11/13
to caa...@googlegroups.com
This seems to be a bug.
You can scale the canvas with director.enableResizeEvents as well.

Thanks.
--
You received this message because you are subscribed to the Google Groups "CAAT javascript framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to caatjs+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Ryan Jarvis

unread,
Jul 11, 2013, 12:57:01 PM7/11/13
to caa...@googlegroups.com
I tried adding director.enableResizeEvents(RESIZE_PROPORTIONAL) but I don't think it handles my specific situation.

That function seems to assume that the canvas should be the same size as the window.  It passes window.innerWidth and window.innerHeight into the setScaleProportional function to determine the factor.  And that factor is used to scale the canvas to match the size of the window.  

What I am trying to do is scale the canvas so that it stays in proportion to the div that contains it (because there are other elements on my page besides the canvas).  For example, if I modify the above example so that the div is larger than the canvas:

<div style="width: 1920px; height: 1080px;">
    <canvas id="CAATCanvas" width="1200px" height="800px" style="width: 1200px; height: 800px;"></canvas>
</div>

What I want is when the window is 1920x1080, the canvas is 1200x800.  When the window is 960x540 (50% smaller), the canvas should be 600x400 (50% smaller).  Is there a way currently I can do this?  Or do you know where you think the original bug could be causing the hit detection to be off so I can poke around?  Thanks.
To unsubscribe from this group and stop receiving emails from it, send an email to caatjs+unsubscribe@googlegroups.com.

hyperandroid

unread,
Jul 11, 2013, 3:13:57 PM7/11/13
to caa...@googlegroups.com
I think the problem is that caat is not using boundingClientRect to find on-canvas coordinate.
Could you post a short sample with the problem (ie an scene with an actor and the css applied to the canvas) ?
To unsubscribe from this group and stop receiving emails from it, send an email to caatjs+un...@googlegroups.com.

hyperandroid

unread,
Jul 11, 2013, 3:20:40 PM7/11/13
to caa...@googlegroups.com
I think the problem is that caat is not using boundingClientRect to find on-canvas coordinate.
Could you post a short sample with the problem (ie an scene with an actor and the css applied to the canvas) ?
To unsubscribe from this group and stop receiving emails from it, send an email to caatjs+un...@googlegroups.com.

hyperandroid

unread,
Jul 11, 2013, 3:44:54 PM7/11/13
to caa...@googlegroups.com
I got a test case.
Will see what's going on.

Thanks.

hyperandroid

unread,
Jul 11, 2013, 4:50:59 PM7/11/13
to caa...@googlegroups.com
Hi Ryan,

i have made some changes to the coordinate identification routine.
Could you please, substitute the function getCanvasCoord in the Director object for this one, and let me know whether this works for you ?
I could send you a complete caat.js file if needed.
thanks.

   getCanvasCoord:function (point, e) {

                var pt = new CAAT.Math.Point();
                var posx = 0;
                var posy = 0;

                /**
                 * Chrome.
                 * offsetX and offsetY is the actual coordinate in the DOM element, regardless the affine transformation
                 * it has applied.
                 */
                if (typeof e.offsetX!=="undefined") {
                    posx= e.offsetX;
                    posy= e.offsetY;
                } else
                /**
                 * FF
                 * clientX and clientY are, more or less, in canvas coordinates.
                 * But must be corrected with scale, calculated from bouding client rect reported size, and actual size.
                 * This won't work right with rotated canvas objects.
                 */
                if ( typeof e.clientX!=="undefined" && this.canvas.getBoundingClientRect ) {
                    var bcr= this.canvas.getBoundingClientRect();
                    posx= (e.clientX - bcr.left) * (this.canvas.width/bcr.width);
                    posy= (e.clientY - bcr.top) * (this.canvas.height/bcr.height);
                } else {

                    /**
                     * older browsers.
                     * survival model. try to find things on your own by traversing upwards the DOM tree.
                     */
                    if (!e) e = window.event;

                    if (e.pageX || e.pageY) {
                        posx = e.pageX;
                        posy = e.pageY;
                    }
                    else if (e.clientX || e.clientY) {
                        posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
                        posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
                    }

                    var offset = this.getOffset(this.canvas);

                    posx -= offset.x;
                    posy -= offset.y;
                }

                posx*= this.SCREEN_RATIO;
                posy*= this.SCREEN_RATIO;

                //////////////
                // transformar coordenada inversamente con affine transform de director.

                pt.x = posx;
                pt.y = posy;
                if (!this.modelViewMatrixI) {
                    this.modelViewMatrix.getInverse(this.modelViewMatrixI);
                }
                this.modelViewMatrixI.transformCoord(pt);
                posx = pt.x;
                posy = pt.y

                point.set(posx, posy);
                this.screenMousePoint.set(posx, posy);

            },

Ryan Jarvis

unread,
Jul 12, 2013, 8:34:17 AM7/12/13
to caa...@googlegroups.com
Yep, this appears to fix the issue in my project.

This function is where the screen coordinates are translating into the world coordinates, correct?  That's what I started noticing last night, I logged the mouseEvents x,y when I clicked and saw they weren't where I thought they were.

Thank you so much!

hyperandroid

unread,
Jul 12, 2013, 6:19:25 PM7/12/13
to caa...@googlegroups.com
Hi Ryan,

Yes. The fix is when translating input coords into canvas coordinates.
From there, they are translated into world coordinates.

It is a shame that modern browsers don't offer a common way of getting exact coordinates in any DOM element regardless its affine transform. 
Hence the variability of the method.

Glad this fixed your problem.

- i

2013/7/12 Ryan Jarvis <ry...@clua.ws>
To unsubscribe from this group and stop receiving emails from it, send an email to caatjs+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages