skip to Main Content

I am trying to create a CSS animation that moves horizontally from left to right while appearing to get closer and further away, simulating the motion of a glass on a turntable platter viewed from the front.

I have got close but its still not looking right, looks like at the moment its travelling along a diamond shape rather than a circle.

Here is what I have tried..

.roll {
  display: block;
  width: 100px;
  height: 100px;
  background: red;
  margin: 10px auto 10px auto;
  animation: roll 2s cubic-bezier(0.42, 0, 0.58, 1) infinite;
}

@keyframes roll {
  0%,
  100% {
    transform: translateX(0%) scale(1);
  }
  20% {
    transform: translateX(50%) scale(0.8);
  }
  50% {
    transform: translateX(0%) scale(0.6);
  }
  80% {
    transform: translateX(-50%) scale(0.8);
  }
}
<div class="roll"></div>

2

Answers


  1. You can achieve this 3d effect by playing with the z-axis. Have a look: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/translateZ

    div {
      width: 50px;
      height: 50px;
      margin: auto;
      background: tomato;
      perspective: 500px;
      transform-style: preserve-3d;
      animation: roll 2s linear infinite;
    }
    
    @keyframes roll {
      0% {
        transform: rotateY(0deg) translatez(110px) scale(1);
      }
      50% {
        transform: rotateY(180deg) translatez(110px) scale(0.5)
      }
      100% {
        transform: rotateY(360deg) translatez(110px) scale(1);
      }
    }
    <div></div>
    Login or Signup to reply.
  2. If you want to animate the square on a horizontal plane circle and keep it facing the viewer, you can use 3d transforms on a wrapper element and resverse it on the square so it stays facing the viewer.

    The point is to rotate the element on the Y axis as it would "in real life".
    Here is an example :

    .wrap {
      width: 100px;
      height: 100px;  
      margin: 50px auto 50px auto;
      animation: roll 2s linear infinite;
      transform-origin: 50% 50% -250px;
      transform-style: preserve-3d;
    }
    .roll {
      width: inherit;
      height: inherit;
      background: red;
      animation: roll 2s linear infinite reverse;
      transform-origin: 50% 50% 0;
    }
    
    @keyframes roll {
      from { transform:  perspective(1200px) rotateY(0deg);}
      to { transform:  perspective(1200px) rotateY(-360deg);}
    }
    <div class="wrap">
      <div class="roll"></div>
    </div>

    Note that you need to use transform-style: preserve-3d; (more info on MDN)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search