Cube spinning on its corner - html

I have a 3D cube made from pure HTML-cum-CSS which is supposed to spin on one of its corners without the corner moving around the screen. Unfortunately, it doesn't quite do so, it rather wobbles along a line (2D) or around a circle (3D). What am I doing wrong?
#cube {
position: relative;
margin: 100px auto;
height: 100px;
width: 100px;
animation: 4s rotateforever infinite linear;
transform-style: preserve-3d;
}
.face {
position: absolute;
height: 78px;
width: 78px;
padding: 10px;
border: black 2px solid;
}
.one {
transform: rotateX(-45deg) rotateY(45deg) translateZ(50px);
}
.two {
transform: rotateX(-45deg) rotateY(135deg) translateZ(50px);
}
.three {
transform: rotateX(-45deg) rotateY(225deg) translateZ(50px);
}
.four {
transform: rotateX(-45deg) rotateY(315deg) translateZ(50px);
}
.five {
transform: rotateX(45deg) rotateZ(-45deg) translateZ(50px);
}
.six {
transform: rotateX(45deg) rotateY(180deg) rotateZ(-45deg) translateZ(50px);
}
#keyframes rotateforever {
to {
transform: rotateY(360deg);
}
}
<body>
<div id="cube">
<div class="face one">one</div>
<div class="face two">two</div>
<div class="face three">three</div>
<div class="face four">four</div>
<div class="face five">five</div>
<div class="face six">six</div>
</div>
</body>
JSFiddle

Found the answer:
According to a post on Blender the left and right angle between the horizontal and the cube in its original position is not 45deg (as I assumed), but only 35.2644deg.
Therefore in my CSS, I had to change the values of each occurrence of a transform: rotateX(...) to 35.2644deg where I used to have 45deg and to 54.7356deg (90 - 35.2644) where I used to have -45deg.
Like so:
.one {
transform: rotateX(-54.7356deg) rotateY(45deg) translateZ(50px);
}
.two {
transform: rotateX(-54.7356deg) rotateY(135deg) translateZ(50px);
}
.three {
transform: rotateX(-54.7356deg) rotateY(225deg) translateZ(50px);
}
.four {
transform: rotateX(-54.7356deg) rotateY(315deg) translateZ(50px);
}
.five {
transform: rotateX(35.2644deg) rotateZ(-45deg) translateZ(50px);
}
.six {
transform: rotateX(35.2644deg) rotateY(180deg) rotateZ(-45deg) translateZ(50px);
}
I updated the JSFiddle.

Related

Animating faces on a CSS isometric cube

I'm trying to animate the faces of an isometric cube I've created using CSS transforms to create an 'unpacking/unfolding' effect.
I want the lid of the cube to rotate upwards but at the moment it floats off rather than rotates from the edge. It starts and ends in the right places. I've tried changing the transform-origin property but it doesn't make a difference. Here's my code so far:
https://jsfiddle.net/wrgt1/5yrLjnw3/38/
html body {
position: relative;
height: 100vh;
width: 100vw;
background-color: #C4C5C4;
}
.front,
.back {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
}
.front {
z-index: 99;
}
.cube {
transform-style: preserve-3d;
transform: rotateX(-35deg) rotateY(45deg);
}
.face {
position: absolute;
width: 30vh;
height: 30vh;
background: white;
border: solid 1px blue;
}
.top {
transform-origin: 100% 100%;
transform: rotateX(90deg) rotateY(0deg) translate3d(15vh, 0, 15vh);
animation: rotatelid 5s linear infinite alternate;
}
.frontleft {
transform: rotateY(-90deg) translate3d(0, 0, 15vh);
}
.frontright {
transform: translate3d(0, 0, 15vh);
}
.backleft {
transform: translate3d(0, 0, -15vh);
background: lightgrey;
}
.backright {
transform: rotateY(-90deg) translate3d(0, 0, -15vh);
}
#keyframes rotatelid {
from {
transform: rotateX(90deg) rotateY(0deg) translate3d(15vh, 0, 15vh);
}
to {
transform: rotateX(90deg) rotateY(90deg) translate3d(-15vh, 0vh, 15vh);
}
}
<div class='front'>
<div class='cube'>
<div class='face top'></div>
<div class='face frontleft'></div>
<div class='face frontright'></div>
</div>
</div>
<div class='back'>
<div class='cube'>
<div class='face backleft'></div>
<div class='face backright'></div>
</div>
</div>
Does anyone know how to solve this problem, or if there's a better way to create simple animations on the web (possibly using SVGs?).
Update the order of your transformation to first translate the element then rotate it. Pay attention to the translation because it's no more the same when added first.
html body {
position: relative;
height: 100vh;
margin:0;
background-color: #C4C5C4;
}
.front,
.back {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
}
.front {
z-index: 99;
}
.cube {
transform-style: preserve-3d;
transform: rotateX(-35deg) rotateY(45deg);
}
.face {
position: absolute;
width: 30vh;
height: 30vh;
background: white;
border: solid 1px blue;
box-sizing:border-box;
}
.top {
transform-origin: 100% 100%;
transform: translate3d(15vh, -15vh, 0vh) rotateX(90deg) rotateY(0deg);
animation: rotatelid 5s linear infinite alternate;
}
.frontleft {
transform: rotateY(-90deg) translate3d(0, 0, 15vh);
}
.frontright {
transform: translate3d(0, 0, 15vh);
}
.backleft {
transform: translate3d(0, 0, -15vh);
background: lightgrey;
}
.backright {
transform: rotateY(-90deg) translate3d(0, 0, -15vh);
}
#keyframes rotatelid {
from {
transform:translate3d(15vh, -15vh, 0vh) rotateX(90deg) rotateY(0deg);
}
to {
transform:translate3d(15vh, -15vh, 0vh) rotateX(90deg) rotateY(90deg);
}
}
<div class='front'>
<div class='cube'>
<div class='face top'></div>
<div class='face frontleft'></div>
<div class='face frontright'></div>
</div>
</div>
<div class='back'>
<div class='cube'>
<div class='face backleft'></div>
<div class='face backright'></div>
</div>
</div>

3D cube movement along the rhombus path

html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background: #eaeaea;
}
.stage {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
perspective: 1800px;
transform-style: preserve-3d;
}
.box {
position: absolute;
top: 50%;
left: 50%;
width: 3.75rem;
height: 3.75rem;
transform-style: preserve-3d;
transform: rotateX(-35deg) rotateY(45deg);
}
.box:nth-child(1) {
animation: box 4s linear;
}
.box:nth-child(1) .left {
animation: left-side 4s linear;
}
.box:nth-child(1) .right {
animation: right-side 4s linear;
}
.box .front,
.box .back,
.box .top,
.box .bottom,
.box .left,
.box .right {
position: absolute;
top: 0;
left: 0;
width: 3.75rem;
height: 3.75rem;
transform-origin: center center;
}
.box .front {
background: #665867;
transform: translateZ(1.875rem);
}
.box .back {
background: #665867;
transform: translateZ(-1.875rem);
}
.box .top {
background: #706171;
transform: translateY(-50%) rotateX(90deg);
}
.box .bottom {
background: #423943;
transform: translateY(50%) rotateX(90deg);
}
.box .left {
background: #776778;
transform: translateX(-50%) rotateY(90deg);
}
.box .right {
background: #524652;
transform: translateX(50%) rotateY(90deg);
}
#keyframes box {
0% {
transform: rotateX(-35deg) rotateY(45deg) translateX(-100px);
}
20% {
transform: rotateX(-35deg) rotateY(45deg) translateX(100px);
}
25% {
transform: rotateX(-35deg) rotateY(45deg) translateX(100px) rotateY(90deg);
}
45% {
transform: translateX(100px) rotateX(-35deg) rotateY(135deg) translateX(200px);
}
50% {
transform: translateX(100px) rotateX(-35deg) rotateY(135deg) translateX(200px) rotateY(90deg);
}
70% {
transform: translateX(-100px) rotateX(-35deg) rotateY(225deg) translateX(100px);
}
75% {
transform: translateX(-100px) rotateX(-35deg) rotateY(225deg) translateX(100px) rotateY(90deg);
}
95% {
transform: translateX(0px) rotateX(-35deg) rotateY(315deg) translateX(100px);
}
100% {
transform: translateX(0px) rotateX(-35deg) rotateY(315deg) translateX(-100px) rotateY(90deg);
}
}
<div class="stage">
<div class="box">
<div class="front"></div>
<div class="back"></div>
<div class="top"></div>
<div class="bottom"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</div>
I'm trying to make a 3D cube move along the path of a rhombus. In each corner of the rhombus (there are 4 of them), it should rotate 90 degrees and continue to move. I managed to do half of the animation path correctly, but in the rest of the animation (after 50%) some kind of nonsense occurs. What am I doing wrong?
You need to keep adding a new transformation to all the previous one without changing them to have a continuous animation. Each step you either translate or rotate until you finish all the path and you get back to the initial one.
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background: #eaeaea;
}
.stage {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
perspective: 1800px;
transform-style: preserve-3d;
}
.box {
position: absolute;
top: 50%;
left: 50%;
width: 3.75rem;
height: 3.75rem;
transform-style: preserve-3d;
transform: rotateX(-35deg) rotateY(45deg);
}
.box:nth-child(1) {
animation: box 4s linear infinite;
}
.box:nth-child(1) .left {
animation: left-side 4s linear;
}
.box:nth-child(1) .right {
animation: right-side 4s linear;
}
.box .front,
.box .back,
.box .top,
.box .bottom,
.box .left,
.box .right {
position: absolute;
top: 0;
left: 0;
width: 3.75rem;
height: 3.75rem;
transform-origin: center center;
}
.box .front {
background: #665867;
transform: translateZ(1.875rem);
}
.box .back {
background: #665867;
transform: translateZ(-1.875rem);
}
.box .top {
background: #706171;
transform: translateY(-50%) rotateX(90deg);
}
.box .bottom {
background: #423943;
transform: translateY(50%) rotateX(90deg);
}
.box .left {
background: #776778;
transform: translateX(-50%) rotateY(90deg);
}
.box .right {
background: #524652;
transform: translateX(50%) rotateY(90deg);
}
#keyframes box {
0% {
transform: rotateX(-35deg) rotateY(45deg);
}
20% {
transform: rotateX(-35deg) rotateY(45deg) translateX(100px);
}
25% {
transform: rotateX(-35deg) rotateY(45deg) translateX(100px) rotateY(90deg);
}
45% {
transform: rotateX(-35deg) rotateY(45deg) translateX(100px) rotateY(90deg) translateX(100px);
}
50% {
transform: rotateX(-35deg) rotateY(45deg) translateX(100px) rotateY(90deg) translateX(100px) rotateY(90deg);
}
70% {
transform: rotateX(-35deg) rotateY(45deg) translateX(100px) rotateY(90deg) translateX(100px) rotateY(90deg) translateX(100px);
}
75% {
transform: rotateX(-35deg) rotateY(45deg) translateX(100px) rotateY(90deg) translateX(100px) rotateY(90deg) translateX(100px) rotateY(90deg);
}
95% {
transform: rotateX(-35deg) rotateY(45deg) translateX(100px) rotateY(90deg) translateX(100px) rotateY(90deg) translateX(100px) rotateY(90deg) translateX(100px);
}
100% {
transform: rotateX(-35deg) rotateY(45deg) translateX(100px) rotateY(90deg) translateX(100px) rotateY(90deg) translateX(100px) rotateY(90deg) translateX(100px) rotateY(90deg);
}
}
<div class="stage">
<div class="box">
<div class="front"></div>
<div class="back"></div>
<div class="top"></div>
<div class="bottom"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</div>

How to expand the sides of a cube while it rotate?

I want to expand the sides of a cube while it rotate like in this pen.
I have tried to create a cube that will spin along x axis but while doing so I want it to also expand its sides after some duration.
Below is my code...
.wrapper{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.cube-wrap {
width: 40px;
height: 40px;
-webkit-perspective: 2000px;
-webkit-perspective-origin: 50% -500px;
}
.single-box {
display: block;
position: absolute;
width: 40px;
height: 40px;
background-color: #60c2ef;
-webkit-transform: rotateY(45deg) translateZ(-200px) rotateX(15deg);
-webkit-transform-origin: 50% 50% 0;
}
.box {
-webkit-transform-style: preserve-3d;
-webkit-animation: rotate 1.5s infinite linear;
}
.side-front {
background-color: blue;
-webkit-transform: translateZ(20px);
}
.side-back {
background-color: blue;
-webkit-transform: rotateY(180deg) translateZ(20px);
}
.side-top {
background-color: blue;
-webkit-transform: rotateX(90deg) translateZ(20px);
}
.side-bottom {
background-color: blue;
-webkit-transform: rotateX(-90deg) translateZ(20px);
}
.side-left {
background-color: blue;
-webkit-transform: rotateY(-90deg) translateZ(20px);
}
.side-right {
background-color: blue;
-webkit-transform: rotateY(90deg) translateZ(20px);
}
#-webkit-keyframes rotate {
0% { -webkit-transform: rotateY(0); }
100% { -webkit-transform: rotateY(360deg); }
}
<div class="wrapper">
<div class="cube-wrap">
<div class="box">
<div class="single-box side-back"></div>
<div class="single-box side-top"></div>
<div class="single-box side-bottom"></div>
<div class="single-box side-left"></div>
<div class="single-box side-right"></div>
<div class="single-box side-front"></div>
</div>
</div>
</div>
The above code will rotate along x axis. It is fine. Along with that, say after 3s or so, I want the cube to rotate slowly and expand along the sides... How can I do it? Could someone help me with this?
This might sound like a stupid answer.. but the answer is actually already in the Codepen that you provided yourself.
In case you're unfamiliair with sass/codepen.
In codepen you can select the dropdown icon and choose for view copiled css
I would suggest to copy the already existing code and then customize it to your own needs.
You could also fork the pen and change it in the codepen environment.

Coinflip animation not spinning correctly (and multiple transforms in css animation)

Alright, so I have two problems, the first problem is that I want the animation to rotate over the X-axes, but it looks weird, because it's not spinning inside each other, Fiddle
Then my other problem is, when I add something like scale(1.5) to the transform animation, it just seems to ignore the rotation, it just won't work anymore.
HTML
<div class="coin-wrapper">
<div class="animate coin">
<div class="terrorist"></div>
<div class="counter-terrorist"></div>
</div>
</div>
CSS
.animate{
animation: rotate 5s;
}
#-webkit-keyframes rotate {
from {
-webkit-transform: rotateY(0);
-moz-transform: rotateY(0);
transform: rotateY(0);
}
to {
-webkit-transform: rotateX(2160deg);
-moz-transform: rotateX(2160deg);
transform: rotateX(2160deg);
}
}
.coin-wrapper {
width: 200px;
height: 200px;
position: absolute;
top: calc(50% - 100px);
left: calc(50% - 100px);
}
.coin {
position: relative;
width: 200px;
transform-style: preserve-3d;
}
.coin .counter-terrorist, .coin .terrorist {
position: absolute;
width: 200px;
height: 200px;
}
.coin .terrorist {
border-radius: 50%;
background-image:url('https://csgoloto.com/template/img/terrorist.png');
background-size:cover;
}
.coin .counter-terrorist {
transform: rotateY(180deg);
border-radius: 50%;
background-image:url('https://csgoloto.com/template/img/counter-terrorist.png');
background-size:cover;
}
The height of the .coin element is being calculated as 0, so that's where the transform-origin is. If you make the coin fill its parent, then it looks good. You can work around the scaling problem by applying scale to the wrapper instead of the coin.
.animate{
animation: rotate 5s;
}
.coin-wrapper {
animation: scale 5s;
}
#-webkit-keyframes rotate {
from {
-webkit-transform: rotateY(0);
-moz-transform: rotateY(0);
transform: rotateY(0);
}
to {
-webkit-transform: rotateX(2160deg);
-moz-transform: rotateX(2160deg);
transform: rotateX(2160deg);
}
}
#-webkit-keyframes scale {
from {
-webkit-transform: scale(1);
-moz-transform: scale(1);
transform: scale(1);
}
to {
-webkit-transform: scale(1.5);
-moz-transform: scale(1.5);
transform: scale(1.5);
}
}
.coin-wrapper {
width: 200px;
height: 200px;
position: absolute;
top: calc(50% - 100px);
left: calc(50% - 100px);
}
.coin {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
}
.coin .counter-terrorist, .coin .terrorist {
position: absolute;
width: 200px;
height: 200px;
}
.coin .terrorist {
border-radius: 50%;
background-image:url('https://csgoloto.com/template/img/terrorist.png');
background-size:cover;
}
.coin .counter-terrorist {
transform: rotateY(180deg);
border-radius: 50%;
background-image:url('https://csgoloto.com/template/img/counter-terrorist.png');
background-size:cover;
}
<div class="coin-wrapper">
<div class="animate coin">
<div class="terrorist"></div>
<div class="counter-terrorist"></div>
</div>
</div>

Abnormal CSS3 Animation Behaviour

I am trying to learn CSS3 by making a simple image slider using animations.
I have successfully achieved the animation pattern to my needs by doing some calculation but the problem is the subsequent images are not following the same rule which is a totally strange behaviour because all I did was change the %age steps for other images as the animation pattern is absolutely same for all of them. But due some unknown reasons, other images are not following as expected and I don't see any logical reason. May be you could help me out!
jsFiddle
HTML:
<div id='slideshow'>
<figure id='imagestrip'>
<img src="images/img2.jpg" alt="Photograph of a Black kite">
<img src="images/img3.jpg" alt="Profile of a Red kite">
<img src="images/img4.jpg" alt="Pelicans on moorings at sea">
<img src="images/img9.jpg" alt="Photograph of Pariah kite">
</figure>
</div>
CSS:
#slideshow {
width: 80%;
margin: 0 auto;
height: 20em;
position: relative;
overflow: hidden;
perspective: 850px;
/* outline: 3px solid blue;*/
}
#slideshow figure {
position: absolute;
width: 400%;
height: 100%;
margin: 0;
transform-style: preserve-3d;
animation: slider2 30s infinite;
outline: 2px solid red;
}
figure img {
width: 25%;
height: 100%;
float: left;
outline: 3px solid yellow;
}
#keyframes slider2 {
0% {
transform: translateX(0%);
transform: translateZ(0px); /*Zoom-in*/
}
2% {
/* transform: translateX(-25%);*/
transform: translateZ(250px);
}
20% {
transform: translateX(0%);
transform: translateZ(250px);
}
22% {
transform: translateX(0%);
transform: translateZ(0px);
}
25% {
/*transform: translateX(-25%);*/
transform: translateZ(0);
transform: translateX(-25%);
}
27% {
/*transform: translateX(-25%);*/
transform: translateZ(250px);
transform: translateX(-25%);
}
45% {
transform: translateZ(250px);
transform: translateX(-25%);
}
47% {
transform: translateZ(0px);
transform: translateX(-25%);
}
50% {
/*transform: translateZ(100px);*/
transform: translateX(-50%);
/*transform: translateZ(0px);*/
}
57% {
transform: translateZ(250px);
transform: translateX(-50%);
}
75% {
transform: translateZ(250px);
transform: translateX(-50%);
}
77% {
transform: translateZ(0px);
transform: translateX(-50%);
}
80% {
/*transform: translateZ(250px);*/
transform: translateX(-75%);
}
My pattern is as follows:
An image Zooms-in for, say, 1s and stays for a while, say, 5s and then zooms-out again for 1s. then it slides left by transform: translateX(%). This pattern is successful for first image but as the second image slides in, nothing happens, though the animation rules are same for other images.
When you want to specify multiple transforms to an element, they should be set to the same property as space separated values and not add a second transform property with the next transform. If you do it that way, then the latest transform would override the one that was provided earlier within same keyframe.
For example, in the below keyframe only the transform: translateZ(0px) has a value.
0% {
transform: translateX(0%);
transform: translateZ(0px);
}
#slideshow {
width: 80%;
margin: 0 auto;
height: 20em;
position: relative;
overflow: hidden;
perspective: 850px;
/* outline: 3px solid blue;*/
}
#slideshow figure {
position: absolute;
width: 400%;
height: 100%;
margin: 0;
transform-style: preserve-3d;
animation: slider2 30s infinite;
outline: 2px solid red;
}
figure img {
width: 25%;
height: 100%;
float: left;
outline: 3px solid yellow;
}
#keyframes slider2 {
0% {
transform: translateX(0%) translateZ(0px);
}
2% {
transform: translateZ(250px);
}
20% {
transform: translateX(0%) translateZ(250px);
}
22% {
transform: translateX(0%) translateZ(0px);
}
25% {
transform: translateZ(0) translateX(-25%);
}
27% {
transform: translateZ(250px) translateX(-25%);
}
45% {
transform: translateZ(250px) translateX(-25%);
}
47% {
transform: translateZ(0px) translateX(-25%);
}
50% {
transform: translateX(-50%);
}
57% {
transform: translateZ(250px) translateX(-50%);
}
75% {
transform: translateZ(250px) translateX(-50%);
}
77% {
transform: translateZ(0px) translateX(-50%);
}
80% {
transform: translateX(-75%);
}
}
<div id='slideshow'>
<figure id='imagestrip'>
<img src="https://images.unsplash.com/41/NmnKzKIyQsyGIkFjiNsb_20140717_212636-3.jpg?q=80&fm=jpg&s=ce9ba69c9caf7d6483d874466478bc9b" alt="Photograph of a Black kite">
<img src="https://images.unsplash.com/41/NmnKzKIyQsyGIkFjiNsb_20140717_212636-3.jpg?q=80&fm=jpg&s=ce9ba69c9caf7d6483d874466478bc9b" alt="Profile of a Red kite">
<img src="https://images.unsplash.com/41/NmnKzKIyQsyGIkFjiNsb_20140717_212636-3.jpg?q=80&fm=jpg&s=ce9ba69c9caf7d6483d874466478bc9b" alt="Pelicans on moorings at sea">
<img src="https://images.unsplash.com/41/NmnKzKIyQsyGIkFjiNsb_20140717_212636-3.jpg?q=80&fm=jpg&s=ce9ba69c9caf7d6483d874466478bc9b" alt="Photograph of Pariah kite">
</figure>
</div>