Skip to content Skip to sidebar Skip to footer

How To Exact Set A Dynamic Style Transform Using Javascript?

I know method of setting transform, but I want to set the rotate and to keep others such as scale and skew. Perhaps, we can write a function as: // A variable of element, not param

Solution 1:

Note: you should use skewX and/or skewY instead of skew. See the MDN info here.

It would be easier to keep track of the transforms in a variable:

var elRot,    // the rotation 'counter'for the element 'el'
    elScale,  // the scale 'counter'for the element 'el'
    elSkewX,  // the skewX 'counter'for the element 'el'
    elSkewY;  // the skewY 'counter'for the element 'el'

// initialize values
elRot = 0;
elScale = 1;
elSkewX = 0;
elSkewY = 0;

or an object:

var elTranform = {
    rot: 0,   // the rotation 'counter'for the element 'el'
    sca: 1,   // the scale 'counter'for the element 'el'
    skx: 0,   // the skewX 'counter'for the element 'el'
    sky: 0    // the skewY 'counter'for the element 'el'
};

So now you can start with the function (you will still use var el for the element), the first step is getting the values, so you change the arguments given to the function:

// use this with separate varsfunctionsetTransform (element, rotationArg, scaleArg, skewXArg, skewYArg) {
    // how to write some code to set the el transform style...
}

// use this with the objectfunctionsetTransform (element, elTransformArg) {
    // how to write some code to set the el transform style...
}

Next you have re-specify any other transforms that are 'staying', in the example you give, the skewX remains 45deg:

functionsetTransform (element, rotationArg, scaleArg, skewXArg, skewYArg) {
    // the brackets cause the string to be evaluated before being assigned
    element.style.transform = ("rotate() scale() skewX() skewY()");
}

or

functionsetTransform(element, elTransformArg) {
    element.style.transform = ("rotate() scale() skewX() skewY()");
}

Now you have to put the arguments into the string:

functionsetTransform(element, rotationArg, scaleArg, skewXArg, skewYArg) {
    element.style.transform = ("rotate(" + rotationArg + "deg ) scale(" + scaleArg
        + ") skewX(" + skewXArg + "deg ) skewY(" + skewYArg + "deg )");
}

or

functionsetTransform(element, elTransformArg) {
    element.style.transform = ("rotate(" + elTransformArg.rot + "deg ) scale("
        + elTransformArg.sca + ") skewX(" + elTransformArg.skx + "deg ) skewY("
        + elTransformArg.sky + "deg )");
}

A bit messy, so put that string in a variable (this will be beneficial for the prefixes):

functionsetTransform (element, rotationArg, scaleArg, skewXArg, skewYArg) {
    var transformString = ("rotate(" + rotationArg + "deg ) scale(" + scaleArg
        + ") skewX(" + skewXArg + "deg ) skewY(" + skewYArg + "deg )");
    
    // now attach that variable to each prefixed style
    element.style.webkitTransform = transformString;
    element.style.MozTransform = transformString;
    element.style.msTransform = transformString;
    element.style.OTransform = transformString;
    element.style.transform = transformString;
}

or

functionsetTransform (element, elTransformArg) {
    var transformString= ("rotate(" + elTransformArg.rot + "deg ) scale("
        + elTransformArg.sca + ") skewX(" + elTransformArg.skx + "deg ) skewY("
        + elTransformArg.sky + "deg )");
    
    // now attach that variable to each prefixed style
    element.style.webkitTransform = transformString;
    element.style.MozTransform = transformString;
    element.style.msTransform = transformString;
    element.style.OTransform = transformString;
    element.style.transform = transformString;
}

Now call the function:

setTransform(el, elRot, elScale, elSkewX, elSkewY);

or

setTransform(el, elTransform);

To change values, change the variables or object values and call:

elRot = 45;
elSkewX = 30;
setTransform(el, elRot, elScale, elSkewX, elSkewY);

or

elTransform.rot = 45;
elTransform.skx = 30;
setTransform(el, elTransform);

This way you only have to change the 'counter' values for each transform, and call the function to apply the transform. As mentioned above, it is important to keep any transforms that are not changed as this simply replaces the previous CSS value for the transform with the new one. Giving multiple values means only the last one is used (the C part of CSS).

Solution 2:

The absolute best answer here would be a real API that allows us to affect any existing value of computed style without having to parse values. Such a thing exists in some abandonned and non-cross-browser form with the WebkitCSSMatrix API and the W3C "official" equivalent DOMMatrix. I've seen talks of reformatting and consolidating those two APIs, but they don't seem to agree on implementation. Here's a shim to make it work cross-browser : CSSMatrix class from github user arian.

How this works is that you can pass it the computed transform string (ex.: "translsate3d(0px, 0px, 100px) scale(1.2) skew(2)") and it returns an object that you can manipulate with rotate, transform, translate, skew functions. Every functions return an existing instance of itself with the newly manipulated value and you can simply re-apply its "toString" value to the element style property.

A lot of words, but here's an example (Chrome and Safari only because of the WebkitCSSMatrix usage) :

var computedStyle = window.getComputedStyle(document.querySelector('.btn'));
var matrix = newWebKitCSSMatrix(computedStyle.transform);

// Every second, we add +6 degrees of rotation, no need to read the initial value since WebkitCSSMatrix has parsed it for uswindow.setInterval(function(){
  matrix = matrix.rotate(6);
  // matrix = matrix.translate(2, 0, 0);// matrix = matrix.scale(1.8);document.querySelector('.btn').style.transform = matrix.toString();
}, 1000);
body{
			padding-top: 100px;
			text-align: center;
		}

		.btn{
			text-transform: uppercase;
			border-radius:200%;
			border:1px solid #000;
			width: 2em;
			height: 2em;
			display: inline-block;
			text-align: center;
			line-height: 2em;
			text-decoration: none;
			font-family: sans-serif;
			color: #000;
      
      // It is already rotated and scaled
			transition: transform 1000mscubic-bezier(.28,.73,.31,1);
      transform: rotate(45deg);
      -webkit-transform: rotate(45deg);
		}

		.btn:hover{
			background:#000;
			color:#fff;
      
      transform: rotate(0deg) scale(1.5);
		}
<aclass="btn"href="#">|</a>

Solution 3:

May be following will help you...

el.style.webkitTransform = "";el.style.MozTransform = "";el.style.msTransform = "";el.style.OTransform = "";el.style.transform = "";

Post a Comment for "How To Exact Set A Dynamic Style Transform Using Javascript?"