Search code examples
jquerycsspositiontransformscale

Getting top and left of a CSS scaled element's normal state with jQuery?


I'm scaling an element on hover with

 transform: scale(1.2);

Now I need to get the top and left position on hover, but it gives me the top and left of the scaled position.. Makes sense, but I'd like the normal state top and left? Is there an easy way to get this?


Solution

  • Depending on transform-origin and the alignment of your element, you can calculate the additional offset by multiplying the width and height by the multiplier of scaleX and scaleY.

    Example:

    var element = $("#myDiv");
    var prefixes = ["-moz-", "-webkit-", "-o-", "-ms-", ""];
    var transX = 1, transY = 1, originX = .5, originY = .5, match;
    for(var i=0; i<prefixes.length; i++){
        var prefix = prefixes[i];
        var transform = element.css(prefix+"transform");
        if(!transform) continue;
        match = transform.match(/scale\((\d+),(\d+)\)/i);
        if(match){
            transX = match[1];
            transY = match[2];
        } else if(match = transform.match(/scale\((\d+)\)/i)){
            transX = transY = match[1];
        } else if(match = transform.match(/scale[XY]\(\d+\)/i)){
            transX = transform.match(/scaleX\((\d+)\)/i);
            transX = transX ? transX[1] : 1;
            transY = transform.match(/scaleY\((\d+)\)/i);
            transY = transY ? transY[1] : 1;
        }
        var origin = element.css(prefix+"tranform-origin").match(/(\d+)% (\d+)%/); /*Default: 50% 50%*/
        if(origin){
            originX = origin[1]/100;
            originY = origin[2]/100;
        } else {
            //Investigate yourself. What would be the value if it doesn't exist?
        }
    }
    
    if(match){ /*A match has been found, thus transX and transY are defined*/
        /*Width * originX * scaleY =
            width * [relative affected part of element] * [scale factor]
            = adjusted offset*/
        var minusLeft = element.width() * originX * scaleX;
        var minusTop = element.height() * originY * scaleY;
        /*Do something, for example:*/
        element.css("left", "-="+minusLeft+"px");
        element.css("top", "-="+minusTop+"px");
    }