Toolbox
Toolbox

Reputation: 2493

transformOrigin triggered from javascript, rotates incorrect

When using transformOrigin in javascript the rotation does not get correct. Within the settings of transform-origin, I am using X/Y coordinates (100%/50%), since 50% is midpoint per each axis.

The problem: When running the animation both the startpoint and endpoint of animation is correct. During the animation the "line indicator" turns in an angle that seems incorrect. If you imagine the animation as it would be a clock, the "line indicator" is clearly leaving its center when rotating.

Wanted behaviour: I need the moving "line indictor" to move around the backgrounds red center cross. I am looking for a method of performing the rotating using javascript transformOrigin.

var deg = 180;

function myFunction() {
x = document.getElementById("indicator").style;
x.transform = "rotate(" + deg + "deg)";
x.transformOrigin = "100% 50%"; // Rotate in the center of div.
x.transition = "all 3s";
}
.indicator {
  z-index: 3;
  position: absolute;
  background-color: black;
  width: 150px;
  height: 10px;
  margin: 212px 0px 0px 100px;
}

.background-box {
  position: absolute;
  z-index: 1;
  background-color: white;
  height: 300px;
  width: 300px;
  margin: 50px 0px 0px 100px;
}

#button {
  height: 40px;
  width: 180px;
}


.checkmark-horizontal {
  z-index: 2;
  position: absolute;
  background-color: red;
  width: 300px;
  height: 3px;
  margin: 214px 0px 0px 100px;
}

.checkmark-vertical {
  z-index: 2;
  position: absolute;
  background-color: red;
  width: 3px;
  height: 300px;
  margin: 50px 0px 0px 250px;
}
<button id = "button" type = "button" name = "button" onclick = "myFunction()">Move indicator 180 degrees </button>

<div class="background-box"></div>

<div id="indicator" class="indicator"></div>

<div class="checkmark-horizontal"></div>
<div class="checkmark-vertical"></div>

Upvotes: 1

Views: 541

Answers (3)

Temani Afif
Temani Afif

Reputation: 272806

In your case you only need to make it right BUT the issue is that you are applying the transformation at the same time so it may not take effect.

UPDATE

This answer gave the correct reason of the behavior.

var deg = 180;

x = document.getElementById("indicator").style;
x.transformOrigin = "right"; /*set it here before applying the transformation*/

function myFunction() {
  x = document.getElementById("indicator").style;
  x.transform = "rotate(" + deg + "deg)";
  x.transition = "all 3s";
}
.indicator {
  z-index: 3;
  position: absolute;
  background-color: black;
  width: 150px;
  height: 10px;
  margin: 212px 0px 0px 100px;
}

.background-box {
  position: absolute;
  z-index: 1;
  background-color: white;
  height: 300px;
  width: 300px;
  margin: 50px 0px 0px 100px;
}

#button {
  height: 40px;
  width: 180px;
}

.checkmark-horizontal {
  z-index: 2;
  position: absolute;
  background-color: red;
  width: 300px;
  height: 3px;
  margin: 214px 0px 0px 100px;
}

.checkmark-vertical {
  z-index: 2;
  position: absolute;
  background-color: red;
  width: 3px;
  height: 300px;
  margin: 50px 0px 0px 250px;
}
<button id="button" type="button" name="button" onclick="myFunction()">Move indicator 180 degrees </button>

<div class="background-box"></div>

<div id="indicator" class="indicator"></div>

<div class="checkmark-horizontal"></div>
<div class="checkmark-vertical"></div>

Upvotes: 1

Chiller
Chiller

Reputation: 9738

You need to set transform-origin: 100% 50%; before setting the transformation or you can use it directly in css

Edit

According to other answers it is best to not animate the transformOrigin and just animate transform in the transition property

var deg = 180;

function myFunction() {
  x = document.getElementById("indicator").style;
  x.transformOrigin = "100% 50%"; // Rotate in the center of div.
  x.transition = "transform 3s";
  x.transform = "rotate(" + deg + "deg)";



}
.indicator {
  z-index: 3;
  position: absolute;
  background-color: black;
  width: 150px;
  height: 10px;
  margin: 212px 0px 0px 100px;
}

.background-box {
  position: absolute;
  z-index: 1;
  background-color: white;
  height: 300px;
  width: 300px;
  margin: 50px 0px 0px 100px;
}

#button {
  height: 40px;
  width: 180px;
}

.checkmark-horizontal {
  z-index: 2;
  position: absolute;
  background-color: red;
  width: 300px;
  height: 3px;
  margin: 214px 0px 0px 100px;
}

.checkmark-vertical {
  z-index: 2;
  position: absolute;
  background-color: red;
  width: 3px;
  height: 300px;
  margin: 50px 0px 0px 250px;
}
<button id="button" type="button" name="button" onclick="myFunction()">Move indicator 180 degrees </button>

<div class="background-box"></div>

<div id="indicator" class="indicator"></div>

<div class="checkmark-horizontal"></div>
<div class="checkmark-vertical"></div>

Upvotes: 2

Takit Isy
Takit Isy

Reputation: 10081

As you should avoid to use a Timeout when not necessary, I propose you to only add the transition effect on the transform property, like this:

var deg = 180;

function myFunction() {
  x = document.getElementById("indicator").style;
  x.transform = "rotate(" + deg + "deg)";
  x.transformOrigin = "100% 50%";
  x.transition = "transform 3s"; // Don't animate all, only the transform!
}
.indicator {
  z-index: 3;
  position: absolute;
  background-color: black;
  width: 150px;
  height: 10px;
  margin: 212px 0px 0px 100px;
}

.background-box {
  position: absolute;
  z-index: 1;
  background-color: white;
  height: 300px;
  width: 300px;
  margin: 50px 0px 0px 100px;
}

#button {
  height: 40px;
  width: 180px;
}

.checkmark-horizontal {
  z-index: 2;
  position: absolute;
  background-color: red;
  width: 300px;
  height: 3px;
  margin: 214px 0px 0px 100px;
}

.checkmark-vertical {
  z-index: 2;
  position: absolute;
  background-color: red;
  width: 3px;
  height: 300px;
  margin: 50px 0px 0px 250px;
}
<button id="button" type="button" name="button" onclick="myFunction()">Move indicator 180 degrees </button>

<div class="background-box"></div>

<div id="indicator" class="indicator"></div>

<div class="checkmark-horizontal"></div>
<div class="checkmark-vertical"></div>

If you do need to animate all, you can use x.transition = "all 3s, transform-origin 0s";.

Hope it helps.

Upvotes: 1

Related Questions