34

I'm wondering how I can get the scale value of an element?

I have tried $(element).css('-webkit-transform'); which returns matrix(scaleX,0,0,scaleY,0,0); Is there a way of getting scaleX and scaleY only?

Harry Joy
  • 57,133
  • 30
  • 158
  • 207
einstein
  • 12,479
  • 27
  • 79
  • 104

5 Answers5

91

The simplest solution to find out the scale factor between the document and an element is the following:

var element = document.querySelector('...');
var scaleX = element.getBoundingClientRect().width / element.offsetWidth;

This works because getBoundingClientRect returns the actual dimension while offsetWidth/Height is the unscaled size.

Joel
  • 15,043
  • 6
  • 49
  • 38
25

If it was specified by a matrix I guess you can't with a straightforward way, but you can easily parse the value:

var matrixRegex = /matrix\((-?\d*\.?\d+),\s*0,\s*0,\s*(-?\d*\.?\d+),\s*0,\s*0\)/,
    matches = $(element).css('-webkit-transform').match(matrixRegex);

matches[1] will contain scaleX and matches[2] will contain scaleY. If it's possible that other transformations have also been applied, you'd need to slightly tweak the regex, because now it assumes that all other parameters are 0.

A way to just get the scale values might be to remove any transforms, measure the computed width/height of the element and then add them back and measure again. Then divide new/old values. Haven't tried it, but it might work. jQuery itself uses a similar approach for many measurements, it even has an undocumented $.swap() function just for this.

PS: You are using -o-transform -moz-transform and -ms-transform too, right?

Lea Verou
  • 23,130
  • 9
  • 44
  • 47
  • +1 for making me realize that the game ain't worth the candle. I have to do something simpler before I go mad. ^_^ – Robusto Jul 23 '15 at 13:08
  • 2
    If other parameters aren't 0, you we can use `matrixRegex = /matrix\(\s*(-?\d*\.?\d*),\s*(-?\d*\.?\d*),\s*(-?\d*\.?\d*),\s*(-?\d*\.?\d*),\s*(-?\d*\.?\d*),\s*(-?\d*\.?\d*)\)/` – Massale Feb 25 '17 at 11:13
9

If you need to target webkit only (because it's for the iPhone, or iPad) the most reliable and fast way is using the native javascript webkit provides:

node = $("#yourid")[0];
var curTransform = new WebKitCSSMatrix(window.getComputedStyle(node).webkitTransform);
alert(curTransform.a); // curTransform is an object,
alert(curTransform.d); // a through f represent all values of the transformation matrix

You can view a demo here: http://jsfiddle.net/umZHA/

methodofaction
  • 68,083
  • 21
  • 145
  • 162
4

You could use the following:

var element = document.getElementById("elementID");
// returns matrix(1,0,0,1,0,0)
var matrix = window.getComputedStyle(element).transform;
var matrixArray = matrix.replace("matrix(", "").split(",");
var scaleX = parseFloat(matrixArray[0]); // convert from string to number
var scaleY = parseFloat(matrixArray[3]);
// bonus round - gets translate values
var translateX = parseFloat(matrixArray[4]); 
var translateY = parseFloat(matrixArray[5]); // parseFloat ignores ")"
1.21 gigawatts
  • 14,347
  • 30
  • 103
  • 209
  • 1
    I believe you have an extra "matrix" in line 3. Should be var matrixArray = matrix.replace("matrix(", "").split(","); – colin moock Oct 11 '19 at 03:21
2

Too late for the OP but might be useful in the future. There is a straightforward way to do it using splits:

function getTransformValue(element,property){       
        var values = element[0].style.webkitTransform.split(")");
        for (var key in values){
            var val = values[key];              
            var prop = val.split("(");          
            if (prop[0].trim() == property)
                return prop[1];
        }                   
        return false;           
    }

This is webkit specific, but can easily be extended for more browsers modifying the fist line.

caiocpricci2
  • 7,614
  • 10
  • 54
  • 87