I have been playing around with looping of CSS transitions (following this article).
The transition itself could be divided into 4 (looped) phases:
shrinked2=>expanded=>expanded2=>shrinked
These states are represented by 4 classes:
shrinked2 - stateOne
expanded - stateTwo
expanded2 - stateThree
shrinked2 - stateFour
I am, initially, setting the width and height of my element, being transitioned, in percents via id. Then, to trigger transition, I am changing transform: scale
via state classes, listed above.
Up to his point it basically works fine for me, here is demonstration on JSFiddle.
Now, as the next step I would like to center the transitioned element, vertically and horizontally, on the page (and keep it there). I am doing so by adding the following, to the element id:
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
as well as appending each transform:
, in the state classes, with translateX(-50%) translateY(-50%)
. Now this way the scale
is not applied to the element (i.e. size is not changed on transition) - only background
property is affected, transition only happens once (i.e. it is not looped anymore), as if transitionend
was never fired.
Here is the result on JSFiddle. Changing of expected property name (in loopTransition
function) to background
, has not effect (JSFiddle).
I am totally aware that there are lots of other ways to center the element. What I would like to understand is:
- Is it possible to combine
translateX
/translateY
andscale
in the same CSS transition (if yes, what am I doing wrong?) - If element centering with
top: 50%; left: 50%; transform: translateX(-50%) translateY(-50%);
is not compatible with transitions in general orscale
in particular, what is the recommended method to use?
var the_circle = document.getElementById('circle');
the_circle.addEventListener("transitionend", loopTransition);
function startTransition() {
var the_circle = document.getElementById('circle');
if (the_circle.className === 'stateOne paused') {
the_circle.style.transitionDuration = 1;
the_circle.className = 'stateTwo animated';
} else {
stopTransition();
}
}
function stopTransition() {
var the_circle = document.getElementById('circle');
the_circle.style.transitionDuration = "0.5s"
the_circle.className = "stateOne paused"
}
function loopTransition(e) {
var the_circle = document.getElementById('circle');
if (e.propertyName === "transform") {
if (the_circle.className.indexOf('paused') !== -1) {
stopTransition()
} else {
if (the_circle.className === "stateTwo animated") {
the_circle.style.transitionDuration = "1s";
the_circle.className = "stateThree animated";
} else if (the_circle.className === "stateThree animated") {
the_circle.style.transitionDuration = "1s";
the_circle.className = "stateFour animated";
} else if (the_circle.className === "stateFour animated") {
the_circle.style.transitionDuration = "1s";
the_circle.className = "stateOne animated";
} else if (the_circle.className === "stateOne animated") {
the_circle.style.transitionDuration = "1s";
the_circle.className = "stateTwo animated";
}
}
}
}
#circle {
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
position: absolute;
width: 10%;
padding-top: 10%;
border-radius: 50%;
transition: all 1s;
}
.stateOne {
background: #800080;
transform: scale(1.0001, 1.0001) translateX(-50%) translateY(-50%);
}
.stateTwo {
background: #ffe6ff;
transform: scale(2, 2) translateX(-50%) translateY(-50%);
}
.stateThree {
background: #ffe6ff;
transform: scale(2.0001, 2.0001) translateX(-50%) translateY(-50%);
}
.stateFour {
background: #800080;
transform: scale(1, 1) translateX(-50%) translateY(-50%);
}
<div id='circle' class="stateOne paused" onclick=startTransition()></div>