When CSS elements are transformed out of their original location the transform-origin
doesn't move with them; making all subsequent transforms and rotations still originate from it's original transform-origin
( example below ).
There is one way around this that I know of... and that's to keep adding all new transforms to the right of the previous ones. like this: transform: translateY ( -5rem ) rotate( 45deg ) translateY( -10rem ) rotate( 15deg )...
etc. This seems to always start the new transforms from the center of the current element as desired.
the problem
When you are transforming an element based on user input using this technique you will keep adding transforms to the DOM...endlessly. Taking up a lot of memory and causing other unwanted sliding effects ( possibly ).
Here is an animation showing how the transform-origin
doesn't move to the center of the element after each transform:
'use strict';
function firstRotation() {
var v = document.getElementById( 'v-wrp' ),
status = document.getElementById( 'status' )
setTimeout( function() {
status.innerHTML = 'First, the V is rotated around it\'s central axis.\
The <b>transform-origin</b> is centered.';
v.classList.add( 'first-rotation' );
status.classList.add( 'update' );
}, 1000 );
}
function firstTranslation() {
var v = document.getElementById( 'v-wrp' ),
status = document.getElementById( 'status' )
setTimeout( function() {
status.innerHTML = 'Next, the element is translated forward in it\'s \
current orientation. The <b>transform-origin</b> stays\
behind where it was.';
v.classList.remove( 'first-rotation' );
v.classList.add( 'first-translation' );
}, 6000 );
}
function info() {
var v = document.getElementById( 'v-wrp' ),
status = document.getElementById( 'status' )
setTimeout( function() {
status.innerHTML = 'This next animation is where it\'s evident that\
the <b>transform-origin</b> is no longer centered, but\
back where it was at the beginning of these transforms';
}, 11000 );
}
function lastRotation() {
var v = document.getElementById( 'v-wrp' ),
status = document.getElementById( 'status' )
setTimeout( function() {
status.innerHTML = 'This last rotation is far wider than desired because the\
transform origin is back where it started.'
v.classList.remove( 'first-translation' );
v.classList.add( 'last-rotation' );
}, 16000 );
}
function end() {
var v = document.getElementById( 'v-wrp' ),
status = document.getElementById( 'status' )
setTimeout( function() {
status.classList.remove( 'update' );
}, 21000 );
}
function start() {
firstRotation();
firstTranslation();
info();
lastRotation();
end();
}
start();
/* / / / / / / / / / / / / / ANIMATION DEFINITIONS / / / / / / / / / / / / / */
.first-rotation, .first-translation, .update, .last-rotation {
animation-duration: 5s;
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
}
.first-rotation {
animation-name: first-rotation;
}
.first-translation {
animation-name: first-translation;
}
.update {
animation-name: update;
animation-iteration-count: infinite;
}
.last-rotation {
animation-name: last-rotation;
}
/*/ / / / / / / / / / / / / / ANIMATION KEYFRAMES / / / / / / / / / / / / / /*/
@keyframes first-rotation {
100% {
transform: rotate( 315deg );
}
}
@keyframes first-translation {
0% {
transform: rotate( 315deg );
}
100% {
transform: rotate( 315deg ) translate( 0, -5rem );
}
}
@keyframes update {
0% {
background-color: mediumslateblue;
}
}
@keyframes last-rotation {
0% {
transform: rotate( 315deg ) translate( 0, -5rem );
}
100% {
transform: rotate( 400deg ) translate( 0, -5rem );
}
}
<head>
<style>
@import url( "https://fonts.googleapis.com/css?family=Nunito" );
html {
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
font-family: "Nunito", sans-serif;
}
html,
body {
margin: 0;
padding: 0;
}
.v {
display: block;
font-size: 2rem;
transform: rotate( 180deg );
}
p {
width: 100%;
padding: 0.5rem;
position: absolute;
bottom: 0;
left: 0;
}
</style>
</head>
<body>
<div id="v-wrp" class="v-wrp">
<b class="v">V</b>
</div>
<p id="status" class="status"></p>
</body>
the question
I need to find a way in CSS or JS to reset the position of the transform-origin
or move it back to the center of the transformed element. Adding more transforms to the right is one technique that isn't working for me in a real time interactive environment. An attempt can be seen here: Transforms are added...endlessly.
How can I either calculate the location of a transformed element and move the transform-origin
back to it's center OR how can I take multiple transform values and condense them into one value that keeps the element in it's same place?
You can also use
top
andleft
to translate the#v-wrp
. And you can create an animation in thetransform-origin
property. Try it in the<b>
element. I hope it will be working right now.