Get element position without considering any transformation on the element and up the DOM tree :
var el = element,
offsetLeft = 0,
offsetTop = 0;
do{
offsetLeft += el.offsetLeft;
offsetTop += el.offsetTop;
el = el.offsetParent;
} while( el );
Get element position without considering transformation applied to it but keeping any transformation up the DOM tree.
To do so you could try to revert the transform.
You must first set transform-origin
to 0,0,0
and surround yourself your transformation (scale, rotate) width translate(50%,50%) ... translate(-50%, -50%)
.
Here is an example,
change that :
transform: scale(2) rotate(45deg) translate(20px);
transform-origin: 50% 50%; //default value
into
transform: translate(50%, 50%) scale(2) rotate(45deg) translate(-50%,-50%) translate(20px);
transform-origin: 0 0 0;
We need to do that because the matrix returned by getComputedStyle() does not include stuff done with transform-origin. Don't know really why.
Then you can use this code :
function parseTransform(transform){
//add sanity check
return transform.split(/(|,|)/).slice(1,-1).map( function(v){
return parseFloat(v);
});
}
function convertCoord(transformArr, x, y, z){
//add sanity checks and default values
if( transformArr.length == 6 ){
//2D matrix
//need some math to apply inverse of matrix
var t = transformArr,
det = t[0]*t[3] - t[1]*t[2];
return {
x: ( x*t[3] - y*t[2] + t[2]*t[5] - t[4]*t[3] )/det,
y: ( -x*t[1] + y*t[0] + t[4]*t[1] - t[0]*t[5] )/det
}
}
else /*if (transformArr.length > 6)*/{
//3D matrix
//haven't done the calculation to apply inverse of 4x4 matrix
}
}
var elRect = element.getBoundingClientRect(),
st = window.getComputedStyle(element),
topLeft_pos = convertCoord(
parseTransform( st.transform ),
elRect.left,
elRect.top,
st.perspective
);
I won't explain the math part because I think it's beyond the scope of this post. Could still explain it somewhere else (another question maybe ? ).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…