Reputation: 67748
I want to continously flip an element around its Y-axis, displaying four changing texts on the front and back side and always have it turn in the same direction. Each function calls the next one, the last one jumps back to the first. The texts are changed while they are on the backside, i.e. invisible. (BTW: I added perspective and gradients only to make the rotation direction more obvious)
I came up with this (press button to start it):
function turn1() {
$('#front').css({transform: 'rotateY(180deg)'});
$('#back').css({transform: 'rotateY(360deg)'}).delay(2000).text('Back1').promise().then(turn2);
};
function turn2() {
$('#front').css({transform: 'rotateY(360deg)'}).text('Front2');
$('#back').css({transform: 'rotateY(540deg)'}).delay(2000).promise().then(turn3);
};
function turn3() {
$('#front').css({transform: 'rotateY(540deg)'});
$('#back').css({transform: 'rotateY(720deg)'}).delay(2000).text('Back2').promise().then(turn4);
};
function turn4() {
$('#front').css({transform: 'rotateY(720deg)'}).text('Front1');
$('#back').css({transform: 'rotateY(900deg)'}).delay(2000).promise().then(turn1);
};
$('#go').on('click', turn1);
.wrapper {
position: relative;
margin: 20px auto;
width: 180px;
height: 180px;
font-size: 36px;
perspective: 150px;
}
#front, #back {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
transition: transform 2s;
backface-visibility:hidden;
display: flex;
justify-content: center;
align-items: center;
}
#front {
background: linear-gradient(to right, #afc, #4be);
}
#back {
background: linear-gradient(to right, #fa0, #0fa); ;
transform: rotateY(180deg);
}
.x {
text-align: center;
}
button {
padding: 6px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="front">Front1</div>
<div id="back">Back1</div>
</div>
<div class="x"><button id="go">Press to Start</button></div>
As you can see, after the fourth turn (when the first function is called again) the element quickly spins back 540 degrees. I can't find a way to reset the Y-rotation to the initial position of 0 and 180 degrees without it spinning back in the other direction. I tried to add a "reset function" at the end of the function chain which is supposed to set the transform parameters to their initial values (without animation), but that doesn't change anything concerning the previous behaviour.
What am I doing wrong here? Is that possible at all?
function turn1() {
$('#front').css({transform: 'rotateY(180deg)'});
$('#back').css({transform: 'rotateY(360deg)'}).delay(2000).text('Back1').promise().then(turn2);
};
function turn2() {
$('#front').css({transform: 'rotateY(360deg)'}).text('Front2');
$('#back').css({transform: 'rotateY(540deg)'}).delay(2000).promise().then(turn3);
};
function turn3() {
$('#front').css({transform: 'rotateY(540deg)'});
$('#back').css({transform: 'rotateY(720deg)'}).delay(2000).text('Back2').promise().then(turn4);
};
function turn4() {
$('#front').css({transform: 'rotateY(720deg)'}).text('Front1');
$('#back').css({transform: 'rotateY(900deg)'}).delay(2000).promise().then(reset1);
};
function reset1() {
$('#front').css({transform: 'none'});
$('#back').css({transform: 'rotateY(180deg)'}).promise().then(turn1);
};
$('#go').on('click', turn1);
.wrapper {
position: relative;
margin: 20px auto;
width: 180px;
height: 180px;
font-size: 36px;
perspective: 150px;
}
#front, #back {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
transition: transform 2s;
backface-visibility:hidden;
display: flex;
justify-content: center;
align-items: center;
}
#front {
background: linear-gradient(to right, #afc, #4be);
}
#back {
background: linear-gradient(to right, #fa0, #0fa); ;
transform: rotateY(180deg);
}
.x {
text-align: center;
}
button {
padding: 6px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="front">Front1</div>
<div id="back">Back1</div>
</div>
<div class="x"><button id="go">Press to Start</button></div>
Upvotes: 0
Views: 3395
Reputation: 272789
The issue is the transition, so one idea is to remove the transition before resetting the position to the initial one.
Here is a basic example:
function turn1() {
$('#front').css({transform: 'rotateY(180deg)',transition:'2s'});
$('#back').css({transform: 'rotateY(360deg)',transition:'2s'}).delay(2000).text('Back1').promise().then(turn2);
};
function turn2() {
$('#front').css({transform: 'rotateY(360deg)'}).text('Front2');
$('#back').css({transform: 'rotateY(540deg)'}).delay(2000).promise().then(turn3);
};
function turn3() {
$('#front').css({transform: 'rotateY(540deg)'});
$('#back').css({transform: 'rotateY(720deg)'}).delay(2000).text('Back2').promise().then(turn4);
};
function turn4() {
$('#front').css({transform: 'rotateY(720deg)'}).text('Front1');
$('#back').css({transform: 'rotateY(900deg)'}).delay(2000).promise().then(reset1);
};
function reset1() {
$('#front').css({transform: 'none',transition:'0s'});
$('#back').css({transform: 'rotateY(180deg)',transition:'0s'}).delay(200).promise().then(turn1);
};
$('#go').on('click', turn1);
.wrapper {
position: relative;
margin: 20px auto;
width: 180px;
height: 180px;
font-size: 36px;
perspective: 150px;
}
#front, #back {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
transition: transform 2s;
backface-visibility:hidden;
display: flex;
justify-content: center;
align-items: center;
}
#front {
background: linear-gradient(to right, #afc, #4be);
}
#back {
background: linear-gradient(to right, #fa0, #0fa); ;
transform: rotateY(180deg);
}
.x {
text-align: center;
}
button {
padding: 6px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="front">Front1</div>
<div id="back">Back1</div>
</div>
<div class="x"><button id="go">Press to Start</button></div>
Upvotes: 1