javascript - How to get the MouseEvent coordinates for an element that has CSS3 Transform? -


i want detect where mouseevent has occurred, in coordinates relative clicked element. why? because want add absolutely positioned child element @ clicked location.

i know how detect when no css3 transformations exist (see description below). however, when add css3 transform, algorithm breaks, , don't know how fix it.

i'm not using javascript library, , want understand how things work in plain javascript. so, please, don't answer "just use jquery".

by way, want solution works mouseevents, not "click". not matters, because believe mouse events share same properties, same solution should work of them.


background information

according dom level 2 specification, mouseevent has few properties related getting event coordinates:

  • screenx , screeny return screen coordinates (the origin top-left corner of user's monitor)
  • clientx , clienty return coordinates relative document viewport.

thus, in order find position of mouseevent relative clicked element content, must math:

ev.clientx - this.getboundingclientrect().left - this.clientleft + this.scrollleft 
  • ev.clientx coordinate relative document viewport
  • this.getboundingclientrect().left position of element relative document viewport
  • this.clientleft amount of border (and scrollbar) between element boundary , inner coordinates
  • this.scrollleft amount of scrolling inside element

getboundingclientrect(), clientleft , scrollleft specified @ cssom view module.

experiment without css transform (it works)

confusing? try following piece of javascript , html. upon clicking, red dot should appear click has happened. version "quite simple" , works expected.

function click_handler(ev) {     var rect = this.getboundingclientrect();     var left = ev.clientx - rect.left - this.clientleft + this.scrollleft;     var top = ev.clienty - rect.top - this.clienttop + this.scrolltop;      var dot = document.createelement('div');     dot.setattribute('style', 'position:absolute; width: 2px; height: 2px; top: '+top+'px; left: '+left+'px; background: red;');     this.appendchild(dot); }  document.getelementbyid("experiment").addeventlistener('click', click_handler, false);  <div id="experiment" style="border: 5px inset #aaa; background: #ccc; height: 400px; position: relative; overflow: auto;">     <div style="width: 900px; height: 2px;"></div>      <div style="height: 900px; width: 2px;"></div> </div> 

experiment adding css transform (it fails)

now, try adding css transform:

#experiment {     transform: scale(0.5);     -moz-transform: scale(0.5);     -o-transform: scale(0.5);     -webkit-transform: scale(0.5);     /* note simple transformation. */     /* remember think more complex ones, described below. */ } 

the algorithm doesn't know transformations, , calculates wrong position. what's more, results different between firefox 3.6 , chrome 12. opera 11.50 behaves chrome.

in example, transformation scaling, multiply scaling factor calculate correct coordinate. however, if think arbitrary transformations (scale, rotate, skew, translate, matrix), , nested transformations (a transformed element inside transformed element), need better way calculate coordinates.

the behaviour experiencing correct, , algorithm isn't breaking. firstly css3 transforms designed not interfere box model.

to try , explain...

when apply css3 transform on element. element assumes kind of relative positioning. in surrounding elements not effected transformed element.

e.g. imagine 3 div's in horizontal row. if apply scale transform decrease size of centre div. surrounding div's not move inwards occupy space once occupied transformed element.

example: http://jsfiddle.net/ashmokhberi/bwwkc/

so in box model, element not change size. it's rendered size changes.

you have keep in mind applying scale transform, elements "real" size same it's original size. changing it's perceived size.

to explain..

imagine create div width of 1000px , scale down 1/2 size. internal size of div still 1000px, not 500px.

so position of dots correct relative div's "real" size.

i modified example illustrate.

instructions

  1. click div , keep mouse in same position.
  2. find dot in wrong position.
  3. press q, div become correct size.
  4. move mouse find dot in correct position clicked.

http://jsfiddle.net/ashmokhberi/ewqlx/

so in order make mouse clicks co-ordinates match visible location on div, need understand mouse giving co-ordinates based on window, , div offsets based on "real" size.

as object size relative window solution scale offset co-ordinates same scale value div.

however can tricky based on set transform-origin property of div. going effect offsets.

see here.

http://jsfiddle.net/ashmokhberi/kmdxj/

hope helps.


Comments

Popular posts from this blog

linux - Using a Cron Job to check if my mod_wsgi / apache server is running and restart -

actionscript 3 - TweenLite does not work with object -

jQuery Ajax Render Fragments OR Whole Page -