1

I have an element with a ton of CSS transformations like this:

transform:  translateX( 0 )
            translateY( -1rem )
            rotate( 45deg ) 
            translateY( -2.5rem )
            rotate( 45deg )
            translateY( 5rem );

The order of these properties matter as they affect how the element ends up being positioned on the page. I've done some tinkering and came up with the same exact end result with fewer properties:

transform:  rotate( 90deg ) translateX( -2.8rem ) translateY( 3.25rem );

You can test this by commenting and uncommenting out the comment in the snippet below to see nothing changes ( the transformations equal the same result ).

I did this manually and it took some time to find the exact transformations that would get me the same result. I'm trying to do this for literally thousands of properties in real time...

Is there a formula? Is there a CSS hack? Is there a simple way of doing this - I don't know where to start. O.o

html {
  display: flex;
  height: 100%; 
  justify-content: center;
  align-items: center;
}

div {
  padding: 2.5rem 1rem;
  background-color: #4cc;
  color: #eee;
  text-align: center;
  border: 1px solid #eee;
  border-radius: 0.25rem;
  
  transform:  translateX( 0 )
              translateY( -1rem )
              rotate( 45deg ) 
              translateY( -2.5rem )
              rotate( 45deg )
              translateY( 5rem );
  
/*transform:  rotate( 90deg ) translateX( -2.8rem ) translateY( 3.25rem );*/
}
<div>
  transformed<br>element
</div>

Edit: You might be wondering: Why do this!? Well here is a problem I had earlier: Move transform-origin back to the center of the element in CSS. I solved it like this: Transforms are added...endlessly . But now I have endless transforms and this is why I ask.

I have tons of dynamic transforms that look like this: enter image description here

Community
  • 1
  • 1
Lynel Hudson
  • 2,335
  • 1
  • 18
  • 34
  • where you want to positioning it? – dippas May 02 '17 at 00:33
  • @dippas I just want it to re-write the transforms with fewer properties. The position can be anywhere. I need to make fewer properties but keep it in the same place and rotation. – Lynel Hudson May 02 '17 at 00:34
  • If you want even less code, just use `transform: rotate( 90deg ) translate( -2.8rem, 3.25rem );` –  May 02 '17 at 01:05
  • Thanks @AnuragDaolagajao. Any idea how to do this systematically? – Lynel Hudson May 02 '17 at 01:29
  • If you are dynamically adding those styles then just get "current-style" and add and overwrite it, instead of appending the transform with more values –  May 02 '17 at 01:31
  • @AnuragDaolagajao That seems like a good suggestion on on the surface but If I don't append the transforms this happens: http://stackoverflow.com/questions/43724514/move-transform-origin-back-to-the-center-of-the-element-in-css. View animation in my snippet. – Lynel Hudson May 02 '17 at 01:33
  • Indeed, I forgot transforms restart from their initial position. Maybe you could use `@keyframes` instead of appending transforms –  May 02 '17 at 01:43
  • Thanks for your help. I'll post the answer if I ever find it...lol – Lynel Hudson May 02 '17 at 01:44
  • 1
    If you use `getComputedStyle` it will return a `matrix`, which will be shortest possible code...like this https://jsfiddle.net/LGSon/7g7gk99s/ ... and with that you can either iterate through all elements or all classes and _shrink_ your code – Asons May 02 '17 at 07:09

1 Answers1

1

I don't know of any other way, but came up with this "hacky" method based on keyframes

UPDATE: Removed jQuery

var currentAngle = 0,
  styleElment = document.createElement('style'), // create a style element to insert dynamic keyframes
  styleSheet,
  animState = 0; // toggle between 2 animation states

document.head.appendChild(styleElment);
styleSheet = styleElment.sheet;

// insert 2 default keyframes to the created stylesheet
styleSheet.insertRule("@keyframes rotate_1 {0% {transform: rotate(0deg);} 100% {transform: rotate(0deg)}}"); // at index 1
styleSheet.insertRule("@keyframes rotate_2 {0% {transform: rotate(0deg);} 100% {transform: rotate(0deg)}}"); // at index 0

document.getElementById("rotateBtn").onclick = function() {
  var newAngle = currentAngle + 30,
    transformCSS = "rotate(" + newAngle + "deg)",
    keyframe_1 = "transform: rotate(" + currentAngle + "deg);",
    keyframe_2 = "transform: rotate(" + newAngle + "deg);",
    animationCSS;

  styleSheet.cssRules[animState][0].style.cssText = keyframe_1; // sets value at 0%
  styleSheet.cssRules[animState][1].style.cssText = keyframe_2; // sets value at 100%

  if (animState === 0) {
    animState = 1;
    animationCSS = "rotate_2 1s";
  } else {
    animState = 0;
    animationCSS = "rotate_1 1s";
  }

  document.getElementById("container").style.animation = animationCSS;
  document.getElementById("container").style.transform = transformCSS;

  currentAngle = newAngle;
};
#container {
  width: 50px;
  height: 50px;
  background: red;
}
<div id="container"></div>
<button id="rotateBtn">Rotate</button>