Get coordinate relative to other elements whith css transform involved
I'm thinking about a way to get coordinate of an element relative to another element when there is transform applied in between (either directly on those elements or somewhere on the dom tree).
We can easily convert coordinate with the used of getComputedStyle().transform which return the matrix to apply. I have a running code doing it.
We could do this way :
All function would take the first element.
- jQuery.toPageCoordinate() would return a function(x,y) to convert coordinate relative to element into document's coordinate. Depending on which use case we want to handle, this may be useless since UIEvents already returns pageX and pageY.
- jQuery.fromPageCoordinate() would return a function(x,y) to convert document's coordinate into coordinate relative to the element.
- jQuery.positionRelativeTo( element2 ) an utility function using the 2 previous one.
Here is the pseudo code for the 2 first :
- toPageCoordinate(){
- var matrix = new Matrix(); //identity matrix
- var el = this[0];
-
- do{
- matrix.translate( el.offsetLeft, el.offsetTop );
-
- var transform = window.getComputedStyle(el).transform;
- if(transform)
- matrix.multiply( parseTransform( transform) );
-
- el = el.offsetParent;
- } while( el );
-
- matrix.inv();
-
- return function(x,y){
- return matrix.applyVect(x, y);
- };
- }
-
- fromPageCoordinate(){
- var matrix = new Matrix(); //identity matrix
- var el = this[0];
- var els = [];
-
- do{
- els.push(el);
- el = el.offsetParent;
- }while( el );
-
- for(var i = els.length-1; i >= 0; i--) {
- el = els[i];
-
- matrix.translate( -el.offsetLeft, -el.offsetTop );
-
- var transform = window.getComputedStyle(el).transform;
- if(transform)
- matrix.multiply( parseTransform( transform) );
- }
-
- return function(x,y){
- return matrix.applyVect(x, y);
- };
- }
The Matrix object is common stuff and parseTransform() shouldn't be difficult :
- parseTransform( transformStr ){
- var floatArr = transformStr.split(/\(|,|\)/).slice(1,-1).map( function(v){
- return parseFloat(v);
- });
-
- if( floatArr.length == 6 )
- build a 3x3 matrix from the 6 values
- else
- build the 4x4 matrix directly from the 16 values
- }
So is this a good idea or does jQuery shouldn't introduce Matrix computation ?
cheers.