Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infinite 360 deg 3d rotation of an isometric shape with nested hover animation

Tags:

html

css

I try to understand how to animate a 3d object with css. Right now i have an isometric type of shape that shows its inside when it's hovered. But additionally i want to animate this isometric shape to turn around 360deg as 3d shape infinite. I've been fiddling with its transform for each box but it doesn't work at all.

Can anyone help me and give some tips or explanations how i can achieve this?

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.cube {
  width: 100px;
  height: 150px;
  position: absolute;
  background-color: red;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: 50% auto;
}

.outterstack .left {
  min-width: 100px;
  min-height: 250px;
  transform-origin: 0 0;
  transform: rotate(90deg) skewX(-30deg) scaleY(0.864);
  background-color: grey;
}

.outterstack .right {
  min-height: 100px;
  min-width: 250px;
  transform-origin: 0 0;
  transform: rotate(-30deg) skewX(-30deg) scaleY(0.864);
  position: relative;
  bottom: 250px;
  background-color: grey;
}

.outterstack .up {
  width: 250px;
  height: 250px;
  transform-origin: 0 0;
  transform: rotate(210deg) skew(-30deg) scaleY(0.864);
  position: relative;
  bottom: 350px;
  background-color: violet;
}

.insidestack .left {
  min-width: 50px;
  min-height: 150px;
  transform-origin: 0 0;
  transform: rotate(90deg) skewX(-30deg) scaleY(0.864);
  background-color: black;
}

.insidestack .right {
  min-height: 100px;
  min-width: 150px;
  transform-origin: 0 0;
  transform: rotate(-30deg) skewX(-30deg) scaleY(0.864);
  position: relative;
  bottom: 149px;
  background-color: yellow;
}

.insidestack .up {
  width: 150px;
  height: 150px;
  transform-origin: 0 0;
  transform: rotate(210deg) skew(-30deg) scaleY(0.864);
  position: relative;
  bottom: 249px;
  background-color: green;
}

.one,
.two,
.three,
.oneins,
.twoins,
.threeins,
.four {
  position: relative;
  left: 150px;
  transition: 1s;
}

.one {
  top: 150px;
  z-index: 7;
}

.oneins {
  bottom: 400px;
  z-index: 1;
}

.two {
  bottom: 740px;
  z-index: 5;
}

.twoins {
  bottom: 1200px;
  z-index: 1;
}

.three {
  bottom: 1630px;
  z-index: 3;
}

.threeins {
  bottom: 2120px;
  z-index: 1;
}

.four {
  bottom: 2520px;
  z-index: 1;
}

.cube:hover .one {
  top: 150px;
  z-index: 7;
}

.cube:hover .oneins {
  bottom: 400px;
  z-index: 6;
}

.cube:hover .two {
  bottom: 650px;
  z-index: 5;
}

.cube:hover .twoins {
  bottom: 1200px;
  z-index: 4;
}

.cube:hover .three {
  bottom: 1450px;
  z-index: 3;
}

.cube:hover .threeins {
  bottom: 2000px;
  z-index: 2;
}

.cube:hover .four {
  bottom: 2250px;
  z-index: 1;
}
<div class="cube">
  <div class="outterstack one">
    <div class="left"></div>
    <div class="right"></div>
    <div class="up"></div>
  </div>
  <div class="insidestack oneins">
    <div class="left"></div>
    <div class="right"></div>
    <div class="up"></div>
  </div>
  <div class="outterstack two">
    <div class="left"></div>
    <div class="right"></div>
    <div class="up"></div>
  </div>
  <div class="insidestack twoins">
    <div class="left"></div>
    <div class="right"></div>
    <div class="up"></div>
  </div>
  <div class="outterstack three">
    <div class="left"></div>
    <div class="right"></div>
    <div class="up"></div>
  </div>
  <div class="insidestack threeins">
    <div class="left"></div>
    <div class="right"></div>
    <div class="up"></div>
  </div>
  <div class="outterstack four">
    <div class="left"></div>
    <div class="right"></div>
    <div class="up"></div>
  </div>
</div>
like image 405
adhi_wika Avatar asked Apr 04 '21 00:04

adhi_wika


People also ask

How to use infinite rotate animation in CSS?

Here you will see the infinite rotate animation in CSS. This trick is so easy and simple, but so effective and enjoyable. With just a few lines of CSS code, you will able rotate an element. This is the part of CSS3 which is the more advanced version of CSS. To do it, we are going to use the CSS @keyframes Rule.

How to rotate text 360 degrees in HTML with CSS?

HTML Code: In this section we will create a basic div element which will have some text inside of it. CSS Code: In this section first we will design the text using basic CSS properties and then we will create the animation using @keyframes rule, we will use the transform property to rotate the text 360 degrees at regular intervals.

What does a rotation matrix look like?

In matrix form, a rotation matrix would look like so: Applied to some point (x, y): Now in code, this would look like so for some angle rot: For each rotation event, all we need to do is update the rot angle that is used to rotate the initial view and update the placement of each tile.

What does isometric projection look like?

Standard isometric projection has it where if we started with the front face of an object, it would be rotated 45 degrees around the vertical axis and then approximately 35 degrees around the horizontal axis. After these transformations, the objects should look roughly like the different shapes in the image below:


2 Answers

You can do this with an css @keyframes animation, but then you need two more side surfaces for each cuboid. Instead the 'up' surfaces from the inner cuboids are not necessary since they are not visible.

Working example:

.cube {
  position: absolute;
  top: 0;
  left: 100px;
  width: 250px;
  height: 250px;
  margin: 50px auto;
  transform-style: preserve-3d;
  animation-name: example;
  animation-duration: 8s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

@keyframes example {
  0% {
    transform: rotateX(-17deg) rotate3d(0, 1, 0, 0deg);
  }
  100% {
    transform: rotateX(-17deg) rotate3d(0, 1, 0, 360deg);
  }
}

.insidestack {
  margin-left: 50px;
}


                                   /* positioning of the cuboids */
.outterstack,
.insidestack {
  position: relative;
  transition: top 1s;
}

.one {
  top: 0;
}

.oneins {
  top: 5px;
}

.two {
  top: 110px;
}

.twoins {
  top: 115px;
}

.three {
  top: 220px;
}

.threeins {
  top: 225px;
}

.four {
  top: 330px;
}


                                   /* positioning when hovered */
.cube:hover .oneins {
  top: 105px;
}

.cube:hover .two {
  top: 210px;
}

.cube:hover .twoins {
  top: 315px;
}

.cube:hover .three {
  top: 420px;
}

.cube:hover .threeins {
  top: 525px;
}

.cube:hover .four {
  top: 630px;
}


                                   /* positioning of the surfaces */
.side,
.flat {
  position: absolute;
}

.outterstack .front {
  transform: translateZ(125px);
}

.outterstack .back {
  transform: rotateY(180deg) translateZ(125px);
}

.outterstack .right {
  transform: rotateY(90deg) translateZ(125px);
}

.outterstack .left {
  transform: rotateY(-90deg) translateZ(125px);
}

.outterstack .up {
  transform: rotateX(90deg) translateZ(125px);
}

.insidestack .front {
  transform: translateZ(75px);
}

.insidestack .back {
  transform: rotateY(180deg) translateZ(75px);
}

.insidestack .right {
  transform: rotateY(90deg) translateZ(75px);
}

.insidestack .left {
  transform: rotateY(-90deg) translateZ(75px);
}


                                   /* styling of the surfaces */
.outterstack .side {
  width: 250px;
  height: 100px;
  border: 1px solid black;
  background-color: grey;
}

.outterstack .flat {
  width: 250px;
  height: 250px;
  background-color: violet;
}

.insidestack .side {
  width: 150px;
  height: 100px;
}

.insidestack .front,
.insidestack .back {
  background-color: yellow;
}

.insidestack .right,
.insidestack .left {
  background-color: black;
}
<div class="cube">
  <div class="outterstack one">
    <div class="side front"></div>
    <div class="side back"></div>
    <div class="side right"></div>
    <div class="side left"></div>
    <div class="flat up"></div>
  </div>
  <div class="insidestack oneins">
    <div class="side front"></div>
    <div class="side back"></div>
    <div class="side right"></div>
    <div class="side left"></div>
  </div>
  <div class="outterstack two">
    <div class="side front"></div>
    <div class="side back"></div>
    <div class="side right"></div>
    <div class="side left"></div>
    <div class="flat up"></div>
  </div>
  <div class="insidestack twoins">
    <div class="side front"></div>
    <div class="side back"></div>
    <div class="side right"></div>
    <div class="side left"></div>
  </div>
  <div class="outterstack three">
    <div class="side front"></div>
    <div class="side back"></div>
    <div class="side right"></div>
    <div class="side left"></div>
    <div class="flat up"></div>
  </div>
  <div class="insidestack threeins">
    <div class="side front"></div>
    <div class="side back"></div>
    <div class="side right"></div>
    <div class="side left"></div>
  </div>
  <div class="outterstack four">
    <div class="side front"></div>
    <div class="side back"></div>
    <div class="side right"></div>
    <div class="side left"></div>
    <div class="flat up"></div>
  </div>
</div>
like image 164
biberman Avatar answered Oct 20 '22 05:10

biberman


take a look at my code. i hope this helps you understand cube rotation.

var current = 0;
var interval = setInterval(function() {}, 1000);
function rotateX() {
  clearInterval(interval);
  interval = setInterval(function() {
    current++;
    document.getElementById("cube").style.transform = "rotate3d(1, 0, 0, "+current+"deg)";
    
    if (current > 360) {
      current = 0;
    }
  }, 30);
}
function rotateY() {
  clearInterval(interval);
  interval = setInterval(function() {
    current++;
    document.getElementById("cube").style.transform = "rotate3d(0, 1, 0, "+current+"deg)";
    
    if (current > 360) {
      current = 0;
    }
  }, 30);
}
function rotateZ() {
  clearInterval(interval);
  interval = setInterval(function() {
    current++;
    document.getElementById("cube").style.transform = "rotate3d(0, 0, 1, "+current+"deg)";
    
    if (current > 360) {
      current = 0;
    }
  }, 30);
}
rotateX();
#cube {
    width: 100px;
    height: 100px;
    transform-style: preserve-3d;
}
.side {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    position: absolute;
    backface-visibility: inherit;
    font-size: 14px;
    color: #fff;
}
.front {
    background: rgba(90,90,90,.7);
    transform: translateZ(50px);
}
.back {
    background: rgba(0,210,0,.7);
    transform: rotateY(180deg) translateZ(50px);
}
.right {
    background: rgba(210,0,0,.7);
    transform: rotateY(90deg) translateZ(50px);
}
.left {
    background: rgba(0,0,210,.7);
    transform: rotateY(-90deg) translateZ(50px);
}
.top {
    background: rgba(210,210,0,.7);
    transform: rotateX(90deg) translateZ(50px);
}
.bottom {
    background: rgba(210,0,210,.7);
    transform: rotateX(-90deg) translateZ(50px);
}
<div id="cube" class="transition-all" style="transform: rotate3d(0, 1, 1, 45deg);">
  <div class="side front">front</div>
  <div class="side back">back</div>
  <div class="side right">right</div>
  <div class="side left">left</div>
  <div class="side top">top</div>
  <div class="side bottom">bottom</div>
</div>

<div style="margin-top: 50px">
<button onclick="rotateX()">rotate X</button>
<button onclick="rotateY()">rotate Y</button>
<button onclick="rotateZ()">rotate Z</button>
</div>
like image 1
Fakt309 Avatar answered Oct 20 '22 06:10

Fakt309