Mohammad Nikdouz
Mohammad Nikdouz

Reputation: 817

How to get value translateX by javascript

content element initialize with javascript

content.children[0].style.transform = "translateX(" + (-200) + "px) scaleX(" + 1.6 + ") scaleY(" + 1.2 + ")";

How to get value of translateX for this element ?

Upvotes: 65

Views: 107043

Answers (7)

caramba
caramba

Reputation: 22480

You can use Window.getComputedStyle()

var element = document.querySelector('.hello');

function getTranslateX() {
  var style = window.getComputedStyle(element);
  var matrix = new WebKitCSSMatrix(style.transform);
  console.log('translateX: ', matrix.m41);
}

document.querySelector('button').addEventListener('click', getTranslateX);

// set inline-style transform to element as given from question
element.style.transform = "translateX(" + (-200) + "px) scaleX(" + 1.6 + ") scaleY(" + 1.2 + ")";
.hello {
    height: 100px;
    width: 100px;
    background: orange;
}
<div class="hello"></div>
<button type="button">get value</button>

Same as above example but using deprecated: style.webkitTransform

var element = document.querySelector('.hello');

function getTranslateX() {
  var style = window.getComputedStyle(element);
  var matrix = new WebKitCSSMatrix(style.webkitTransform);
  console.log('translateX: ', matrix.m41);
}

document.querySelector('button').addEventListener('click', getTranslateX);

// set inline-style transform to element as given from question
element.style.transform = "translateX(" + (-200) + "px) scaleX(" + 1.6 + ") scaleY(" + 1.2 + ")";
.hello {
    height: 100px;
    width: 100px;
    background: orange;
}
<div class="hello"></div>
<button type="button">get value</button>

If you wonder why matrix.m41 that is explained here

Upvotes: 79

MohamedFiky
MohamedFiky

Reputation: 121

A 2021 method :

You can use window.getComputedStyle(element).getPropertyValue("css property") .

Here the css property would be ("transform") .

The result if was a 2d matrix which contain 6 values like this :

matrix(1, 0, 0, 1, 10, 20)

The 5th value is translateX , and the 6th is translateY .

If then you want to manipulate the value from that matrix either increase or decrease you may use split() method to convert it to an array , then turn the value you got from that array into a number as following :

   let matrex = window.getComputedStyle(element).getPropertyValue("transform");
       //matrix(1, 0, 0, 1, 10, 20)
       let matrexArr = matrex.split(", ");
      //Array(6) [ "matrix(1", "0", "0", "1", "10", "20)" ]
       let translateXNum = parseInt(matrexArr[4]);
       //10

NB : I am a newbie programmer , sorry if there is something is not clear enough .

Upvotes: 12

Brend8c
Brend8c

Reputation: 649

I would also like to add. I think this is important.

Get the css value of the transform property. It will output the values of the 3D matrix.
And you will need a specific number to get the value.

One of the 16 values of a 4x4 homogeneous matrix. For example, m12 represents the value in the first row and second column.
Find the value in the matrix for the css property "transform: scaleY (0);" changing 0 in css to 44 eg.

let box = document.querySelector('.menu-1');
let getStyle = getComputedStyle(box);
let matrix = new DOMMatrixReadOnly(getStyle.transform);
console.clear();
console.info("gmatrix.m11 = ", matrix.m11);
console.info("gmatrix.m12 = ", matrix.m12);
console.info("gmatrix.m13 = ", matrix.m13);
console.info("gmatrix.m14 = ", matrix.m14);
console.info("gmatrix.m21 = ", matrix.m21);
console.info("gmatrix.m22 = ", matrix.m22);
console.info("gmatrix.m23 = ", matrix.m23);
console.info("gmatrix.m24 = ", matrix.m24);
console.info("gmatrix.m31 = ", matrix.m31);
console.info("gmatrix.m32 = ", matrix.m32);
console.info("gmatrix.m33 = ", matrix.m33);
console.info("gmatrix.m34 = ", matrix.m34);
console.info("gmatrix.m41 = ", matrix.m41);
console.info("gmatrix.m42 = ", matrix.m42);
console.info("gmatrix.m43 = ", matrix.m43);
console.info("gmatrix.m44 = ", matrix.m44);

Upvotes: 0

Exodus 4D
Exodus 4D

Reputation: 2822

You can play with some experimental features: Element.computedStyleMap()

Current support Chrome & Edge (check: caniuse.com)

Short answer

For single transform [ e.g. transform: translate(40px, 10px); ]:

  • Get the value from index [0]:

    el.computedStyleMap().get('transform')[0].y.value;
    

Demo:

let {
  value,
  unit
} = document.getElementById('demo').computedStyleMap().get('transform')[0].y;

console.log(value, unit); // 10 "px"
body {
  display: flex;
  flex-direction: column;
}

.box {
  align-self: center;
  width: 150px;
  height: 100px;
  opacity: 0.5;
}

#orig {
  position: absolute;
  background-color: blue;
}

#demo {
  background-color: red;
  transform: translate(40px, 10px); /* << */
}
<div id="orig" class="box"></div>
<div id="demo" class="box"></div>


Long answer

For multi transform [ e.g. transform: translate(40px, 10px) scale(0.8, 0.5); ]

  • Search for either instanceof CSSTranslate or CSSScale, …

Demo

  1. Element.computedStyleMap()StylePropertyMapReadOnly instance …

  2. StylePropertyMapReadOnly.get('transform')CSSTransformValue instance …

    el.computedStyleMap().get('transform');`
    
  3. .find() prop. with instanceof CSSTranslate

  4. … extract what you need from coordinate props. E.g. Coordinante X

     const {x: {value, unit}} = [
         ...el.computedStyleMap?.()
         .get('transform')?.values()
     ].find(x => x instanceof CSSTranslate);
    
     console.log(value, unit); // ➜ 40 'px'
    

const el = document.getElementById('demo');
const styleMap = el.computedStyleMap();      // ➜ StylePropertyMapReadOnly
const transform = styleMap.get('transform'); // ➜ CSSTransformValue
// console.log(transform);
/*
CSSTransformValue {
  0: CSSTranslate {
    x: CSSUnitValue {
         value: 40, 
         unit: 'px'
       },
    y: CSSUnitValue {
         value: 10, 
         unit: 'px'
       },
    z: ...
  }, 
  1: CSSScale {
    x: CSSUnitValue {
         value: 0.8, 
         unit: 'number'
       },
    y: CSSUnitValue {
         value: 0.5, 
         unit: 'number'
       }
  }
}
*/

const mx = transform.toMatrix();             // ➜  DOMMatrix
console.log(mx.toString());                  // ➜ 'matrix(0.8,   0,   0, 0.5,  40,  10)'
// console.log(mx)                           //     ⇒       a    b    c    d    e    f  
                                             //     ⇒     m11  m12  m21  m22  m41  m42 
                                        
console.log(transform.toString());           // ➜ 'translate(40px, 10px) scale(0.8, 0.5)' ━┓
const [translate, scale] = transform;        //                                             =
console.log(                                 // ➜ 'translate(40px, 10px) scale(0.8, 0.5)' ━┛
  ...[translate, scale].map(String)
); 

// ... alternative create new CSSTranslate() from CSS string e.g. 'translate(40px, 10px)': 
let translate2 = new CSSTranslate(
  ...translate.toString()                    // ➜ 'translate(40px, 10px)'
  .split(/[(,)]/)                            // ➜ ['translate', '40px', ' 10px', '']
  .slice(1, -1)                              // ➜ ['40px', ' 10px']
  .map(CSSNumericValue.parse)                // ➜ [CSSUnitValue {value: 40, unit: "px"}, ...]
);

const mx2 = translate2.toMatrix();           // ➜  DOMMatrix
console.log(mx2.toString())                  // ➜ 'matrix(1, 0, 0, 1, 40, 10)'
body {
  display: flex;
  flex-direction: column;
}

.box {
align-self: center;
  width: 150px;
  height: 100px;
  opacity: 0.5;
}

#orig {
  position: absolute;
  background-color: blue;
}

#demo {
  background-color: red;
  transform: translate(40px, 10px) scale(0.8, 0.5) /* << */
}
<div id="orig" class="box"></div>
<div id="demo" class="box"></div>

Upvotes: 5

TechWisdom
TechWisdom

Reputation: 4285

A cross browser solution:

function getTranslateXY(element) {
    const style = window.getComputedStyle(element)
    const matrix = new DOMMatrixReadOnly(style.transform)
    return {
        translateX: matrix.m41,
        translateY: matrix.m42
    }
}

Tests

We get this output (in a REPL style):

>> getTranslateXY(element1)
{translateX: 0, translateY: 0}
>> getTranslateXY(element2)
{translateX: 0, translateY: -90}
>> getTranslateXY(element3)
{translateX: 30, translateY: 0}
>> getTranslateXY(element4)
{translateX: 10, translateY: 20}
>> getTranslateXY(element5)
{translateX: -400, translateY: 500}

For those elements as arguments (passed to the aforementioned getTranslateXY function):

<div/>                                                         // element1 
<div style="transform: translateY(-90px);"/>                   // element2 
<div style="transform: translateX(30px);"/>                    // element3
<div style="transform: translateX(10px) translateY(20px);"/>   // element4
<div style="transform: translate3d(-400px, 500px, 0px);"/>     // element5

Pay attention to the mix (or absence) of translateX / translateY and also translate3d. We get proper results, no matter what CSS function we use (translate3d contains values of translateX and translateY).

Explanation

Reagrding the matrix: we have 16 properties named m11, m12, m13 ... m41, m42, m43, m44, that represent the columns and rows of the matrix. We are interested in the fourth column, and in the first and the second row. m41 holds the translateX property, and m42 holds the translateY property.

We use window.getComputedStyle(element) instead of element.style to get a uniformed representation of the transform value (in the form of a matrix), so we won't need to use regex, or parsing strings' headache.

Compatibility

Supported by all major browsers, except the notorious Internet Explorer, achieved by:

  • Using style.transform instead of style.webkitTransform.
  • Using DOMMatrixReadOnly interface instead of WebKitCSSMatrix. (WebKitCSSMatrix is an alias to DOMMatrix, which is a mutable version of DOMMatrixReadOnly, that inherits properties from it).

I made this summary thanks to the great answers and comments in this thread, so the credit is all yours.

Upvotes: 37

Aleksander Stelmaczonek
Aleksander Stelmaczonek

Reputation: 1518

Using matrix parsing method from here I was able to access transformation properties with following code:

var transformation = window.getComputedStyle(myEl).getPropertyValue("transform").match(/(-?[0-9\.]+)/g);

If there is no transformation applied then transformation object will be null, otherwise it will hold array of transformation properties. For 2D transformation it's going to be like this:

matrix(scaleX(),skewY(),skewX(),scaleY(),translateX(),translateY())

Upvotes: 15

dietary-wheevil
dietary-wheevil

Reputation: 4481

If you want to be fancy (and, for that matter, exact), you can use a special method on the Window object. Namely, the .getComputedStyle() method.

Let's say your element has an id of myElement. You could get do as follows:

const myEl = document.getElementById('myElement');
window.getComputedStyle(myEl).transform;

Of course, what is returned reflects the collective effect of all other transformations applied upon the same element (e.g., rotations, translations, scalings, etc.). Furthermore, when querying for the value of transform style property, we tend to get something ugly in the form of a matrix transformation (e.g., "matrix3d(1, 0, 0, 0, 0, 0.939693, 0.34202, 0, 0, -0.34202, 0.939693, 0, 0, 0, 0, 1)"). We probably want to avoid this avenue since, at best, it leaves us with the hassle of having to parse a string output.

My recommendation, then, would be to stay simple and just query the transform property on the style object (more specifically, a CSSStyleDeclaration object). Check it:

const transformStyle = document.getElementById('myElement').style.transform
// => "translateX(1239.32px)"

Again, we get a string-type output, but the hassle has been greatly eased by the simplicity of that string. By leveraging the replace method of the String object's prototype and passing a simple regular expression, we can trim the value of transformStyle to just what we want:

const translateX = transformStyle.replace(/[^\d.]/g, '');
// => "1239.32"

And if you want that output as a Number data type, simply append the + unary operator before the whole statement to coerce into such:

const translateX_Val = +translateX;
// => 1239.32

Edit

Instead of doing

window.getComputedStyle(myEl).transform;

the safer and recommended approach is probably to instead use the getPropertyValue method:

window
  .getComputedStyle(myEl)
  .getPropertyValue('transform');

Upvotes: 32

Related Questions