I made a HTML cube and animated its rotation after clicking on it. The cube rotates 90 degrees each time you click on it. I have an animation that makes 360 degrees.It pauses after 1/4 of animation total duration and runs again after click. That way we can see each of side faces in turn - 1,2,3,4.
But after about 10 clicks it is clear that angle is more than 90 but and view is not isometric anymore.
How to make this cube turn exactly 90 degrees and look right?
Probably it is not good to rely on duration. It could be easier if browser could watch angle and pause animation-play-state on 90, 180, 270, 360 degrees
var spinner = document.getElementById('spinner');
// get animation duration in ms
var animationDuration = parseFloat(window.getComputedStyle(spinner)['animation-duration'])*1000;
spinner.addEventListener('click', function () {
// run animation
spinner.style['animation-play-state'] = 'running';
// pause animation after animationDuration / 4
setTimeout(function () {
spinner.style['animation-play-state'] = 'paused';
}, animationDuration / 4);
});
body {
-webkit-font-smoothing: antialiased;
margin: 0;
}
* {
box-sizing: border-box;
}
.container {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 100px;
color: black;
}
.scene {
position: relative;
width: 120px;
height: 120px;
transform-style: preserve-3d;
transform: rotatex(-33.5deg) rotatey(45deg);
}
.face {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
font-size: 100px;
background: rgba(141, 148, 249, 0.5);
line-height: 100px;
border: 2px solid white;
}
.face-front {
transform: rotateY(360deg) translateZ(60px);
}
.face-right {
transform: rotateY(90deg) translatez(60px);
}
.face-back {
transform: rotateY(180deg) translatez(60px);
}
.face-left {
transform: rotateY(270deg) translateZ(60px);
}
.face-top {
transform: rotatex(90deg) translatez(60px);
}
.face-bottom {
transform: rotatex(-90deg) translatez(60px);
}
#spinner {
position: absolute;
display: inline-block;
width: 120px;
height: 120px;
left: 0;
top: 0;
transform-style: preserve-3d;
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 4s;
animation-play-state: paused;
transform-style: preserve-3d;
}
@keyframes spinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div >
<div >
<div id="spinner">
<div >1</div>
<div >2</div>
<div >3</div>
<div >4</div>
<div >5</div>
<div >6</div>
</div>
</div>
</div>
</body>
</html>
CodePudding user response:
Using the duration isn't recommended as you stated.
One other way is to use the transform
css style, and add 90
degrees to it on each click:
Then we only need one more CSS rule to add some 'animation' to the transform:
transition: transform 1s ease;
var spinner = document.getElementById('spinner');
var scene = document.getElementsByClassName('scene')[0];
let currentRotation = 45;
spinner.addEventListener('click', function () {
currentRotation = 90; // Or change to -= to go clockwise
scene.style['transform'] = `rotatex(-33.5deg) rotatey(${currentRotation}deg)`;
});
body {
-webkit-font-smoothing: antialiased;
margin: 0;
}
* {
box-sizing: border-box;
}
.container {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 100px;
color: black;
}
.scene {
position: relative;
width: 120px;
height: 120px;
transform-style: preserve-3d;
transform: rotatex(-33.5deg) rotatey(45deg);
transition: transform 1s ease;
}
.face {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
font-size: 100px;
background: rgba(141, 148, 249, 0.5);
line-height: 100px;
border: 2px solid white;
}
.face-front {
transform: rotateY(360deg) translateZ(60px);
}
.face-right {
transform: rotateY(90deg) translatez(60px);
}
.face-back {
transform: rotateY(180deg) translatez(60px);
}
.face-left {
transform: rotateY(270deg) translateZ(60px);
}
.face-top {
transform: rotatex(90deg) translatez(60px);
}
.face-bottom {
transform: rotatex(-90deg) translatez(60px);
}
#spinner {
position: absolute;
display: inline-block;
width: 120px;
height: 120px;
left: 0;
top: 0;
transform-style: preserve-3d;
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 4s;
animation-play-state: paused;
transform-style: preserve-3d;
}
@keyframes spinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
<div >
<div >
<div id="spinner">
<div >1</div>
<div >2</div>
<div >3</div>
<div >4</div>
<div >5</div>
<div >6</div>
</div>
</div>
</div>