Translate VS Transform-Origin CSS3

translate vs transform-origin css3

transform-origin changes the point at which the element transforms rather than moving the entire element (as translate would). The default value is transform-origin: 50% 50%;.

Here is an illustration: http://jsfiddle.net/joshnh/73g7t/

Simulating transform-origin using translate

You are almost good but you have two errors. You need to invert the translations and you need to change the transform-origin of the second one.

If you check the documentation, you will see that the reference used to translate the origin is the top left corner of the element and the default value of transform origin is center. So we need to have the same reference for both.

.origin {  transform-origin: 50px 50px;  transform:  rotate(45deg) scale(2);}.translate {  transform-origin:0 0;   transform:translate(50px, 50px) rotate(45deg) scale(2) translate(-50px, -50px);} .box {  background-color: red;  width: 50px;  height: 50px;}.container {  display: inline-block;  margin: 30px;  width: 150px;  height: 150px;  background-color: rgba(0,0,0,0.1);}
<div class="container">  <div class="box origin">  </div></div><div class="container">  <div class="box translate">  </div></div>

Understanding translate after scale in CSS transforms

Since the translation is done after the scale() it will also get scaled so your 320px need to be divided by 0.9 to get the correct value:

320/0.9 = 355.56

In other words, you need to move by 355.56px to actually get the 320px. It's a bit tricky but imagine your self inside another world scaled by 0.9. The perception of the distances outside that world will not be the same inside the scaled world.

A related question to get more details about the math: Why does order of transforms matter? rotate/scale doesn't give the same result as scale/rotate

In your case:

scale(0.9) translate(A, B)

Is equivalent to:

|0.9 0 0|   |1 0 A|   |0.9 0  A*0.9|
|0 0.9 0| x |0 1 B| = |0 0.9 B*0.9|
|0 0 1| |0 0 1| |0 0 1 |

So

Xf =  0.9*(Xi + A);
Yf = 0.9*(Yi + B);

If you do the opposite (translate then scale) you can use 320px

* {
padding: 0;
margin: 0;
}

.container {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 6400px;
height: 3600px;
background-color: red;
transform-origin: 50% 50%;
transform: translate(-320px, -180px) scale(0.9) ;
}
<div class="container">

</div>

transform translate rotate order

Hope this helps

consider the two transform orders:

  1. transform: translateX(value px) rotateY(value deg);

In this case rotateY is done first and then translateX,and you get a broken cube because of transform-origin property.If you remove this it will be perfect.

when the transform-origin property is applied to a translate transform
function that there is no apparent visual difference in the outcome.
This is because the element impacted by the transform is moved without
changing it’s shape, size, or rotation.

.wrap {  display: -webkit-box;  display: -webkit-flex;  display: -ms-flexbox;  display: flex;  -webkit-box-pack: center;  -webkit-justify-content: center;      -ms-flex-pack: center;          justify-content: center;  -webkit-box-align: center;  -webkit-align-items: center;      -ms-flex-align: center;          align-items: center;  -webkit-perspective: 800px;          perspective: 800px;  -webkit-perspective-origin: 50%  100px;          perspective-origin: 50%  100px;  margin-top: 150px;}
.cube { position: relative; width: 200px; -webkit-transform-style: preserve-3d; transform-style: preserve-3d; -webkit-animation: spin 10s linear infinite; animation: spin 10s linear infinite;}
.cube div { position: absolute; width: 200px; height: 200px; text-align: center; color: #66cc00; background: pink;}
.cube .back { -webkit-transform: translateZ(-100px) rotateY(180deg); transform: translateZ(-100px) rotateY(180deg);}
.cube .front { -webkit-transform: translateZ(100px); transform: translateZ(100px);}
.cube .right { -webkit-transform: translateX(100px) rotateY(-270deg); transform: translateX(100px) rotateY(-270deg);}
.cube .left { -webkit-transform: translateX(-100px) rotateY(270deg); transform: translateX(-100px) rotateY(270deg);}
.cube .top { -webkit-transform: translateY(-100px) rotateX(-90deg); transform: translateY(-100px) rotateX(-90deg);}
.cube .bottom { -webkit-transform: translateY(100px) rotateX(90deg); transform: translateY(100px) rotateX(90deg);}
@-webkit-keyframes spin { from { -webkit-transform: rotateY(0); transform: rotateY(0); } to { -webkit-transform: rotateY(360deg); transform: rotateY(360deg); }}
@keyframes spin { from { -webkit-transform: rotateY(0); transform: rotateY(0); } to { -webkit-transform: rotateY(360deg); transform: rotateY(360deg); }}
    <div class="wrap">      <div class="cube">        <div class="front">front</div>        <div class="back">back</div>        <div class="top">top</div>        <div class="bottom">bottom</div>        <div class="left">left</div>        <div class="right">right</div>      </div>    </div>

Reset CSS transform origin after translation / rotation

Resetting the transform origin, as you say is hard

However, you can keep adding transforms on the right side, with the previous ones unchanged, and you'll get what you want.

(As a side note, in a snippet you don't need the body element in the HTML, and the styles are better placed in the CSS editor.)

.tri-bx {  animation-name: start;  animation-duration: 5s;  animation-iteration-count: infinite;}
@keyframes start { 0% { transform: rotate( 0deg); } 33% { transform: rotate( 315deg); } 66% { transform: rotate( 315deg) translate( 0, -5rem) rotate(0deg); } 100% { transform: rotate( 315deg) translate( 0, -5rem) rotate( 405deg); }}
html,body { height: 100%; margin: 0; padding: 0;}
body { display: flex; justify-content: center; align-items: center; background-color: #fdfdfd; color: #aaa; font-family: Arial, 'sans-serif'; font-size: 0.8rem; letter-spacing: 0.1rem;}
.tri { width: 0; height: 0; border-left: 1rem solid transparent; border-right: 1rem solid transparent; border-bottom: 1rem solid #555; transform: scaleY( 2); border-radius: 50%;}
.status,.instr { position: absolute;}
.status { top: 0;}
.instr { bottom: 0;}
<div class="tri-bx">  <div class="tri"></div></div>


Related Topics



Leave a reply



Submit