Tuesday, June 22, 2010

Scrolling with jQuery (and Raphaël.js)

‹prev | My Chain | next›

Up tonight, a quick review of what I did last. I got things working last night, but I slapped it together without much thought.

The solution involved document.elementFromPoint, which finds the topmost (in a z-index sense) element at a given point. Like most folks, I glossed over the documentation when I first started using this method and missed this bit:
pixels relative to the upper-left corner of the document's containing window or frame
I did not expect document.elementFromPoint to account for the margin between the raphaël.js "paper" and the top-left of the document. So I had been manually correcting for that margin:
    var c_el = document.elementFromPoint(avatar.attr("cx") + 8,
avatar.attr("cy") + 8);
Instead of manually adding the 8 pixels, I would like to do it a more repeatable fashion (i.e. so I can change the CSS without needing to change my code). Happily, I am using jQuery in addition to raphaël.js in my (fab) game, so I can use offset(), which returns the coordinates of an element relative to the document (just what I need!).

To translate into game coordinates, I need the offset of the room. Trying to get a jQuery matched set for a raphaël.js paper / SVG element results in an empty matched set. Thankfully (and for that reason), I wrapped the room inside a <div>. Thus I can get access to the offset like so:
$(paper.canvas).parent().offset()
Getting back to my poor reading of the document.elementFromPoint documentation, it had not occurred to me that I needed to account for scrolling. As the documentation states, and as I found from bitter experience last night, I do.

I lucked into the scrollTop() method yesterday, but that turns out to be another of jQuery's magical functions that does exactly what I need it to. It, along with its sister method, scrollLeft(), return the offset of an element relative to the browser viewport. Thus, to get my element at the point of collision in my (fab) game, I simply need:
    var c_x = avatar.attr("cx") +
$(self.avatar.paper.canvas).parent().offset().left +
$(document).scrollLeft();

var c_y = avatar.attr("cy") +
$(self.avatar.paper.canvas).parent().offset().top +
$(document).scrollTop();

var c_el = document.elementFromPoint(c_x, c_y);
Nice to know that I hit pretty close to the mark last night. Even better to know that I hit the mark tonight.

Day #142

No comments:

Post a Comment