skip to Main Content

I have a <div class="sphere" /> that I want to move in the shape of infinity symbol. So I thought the answer should be to fix transform-origin to left, from 0 to 50%, make it do a full rotation, then change transform-origin to right, and from 50.01% to 100% make it do a full rotation again and reset tranform origin like so


.sphere {
        position: absolute;
        width: var(--sphere-dim);
        height: var(--sphere-dim);
        background: rgb(183, 162, 159);
        border-radius: 50%;
        top: 40%;
        left: 40%;
        transform-origin: left;
        /* transition: all 1.5s; */
        /* animation-fill-mode: forwards; */
        animation: infinityWobble 5s infinite;
    }

    @keyframes infinityWobble {
        0% {
            transform: rotate(0deg);
        }
        50% {
            transform: rotate(360deg);
        }
        50.01% {
            transform: rotate(0deg);
            transform-origin: right;
        }
        99% {
            transform: rotate(360deg);
        }
        100% {
            transform-origin: left;
        }
    }

https://codepen.io/meherwan-singh-gill/pen/ExOKxmv

^ this is the result

2

Answers


  1. As I mentioned the rotate animation will be not visible because the element you are rotating is a circle. So in this case you either need to play with transformX and transformY, or another approach will be changing the top and left position of the element. Here is an example. Hope it helps a bit 🙂

    .container
    {
        width: 100px;
        height: 50px;
        position: relative;
    }
    
    .sphere
    {
        width: 10px;
        height: 10px;
        background-color: black;
        border-radius: 40px;
        position: absolute;
        top: 48%; 
        left:1%;
        
       animation: infinity 1s linear infinite;
    }
    
    @keyframes infinity
    {
         6.25%  {top: 21%; left:3%}
        12.5%  {top: 7%; left:11%;}
        18.75%  {top: 12%; left:25%;}
        25% {top: 48%; left:47%;}
        
        31.25%  {top: 84%;  left:71%;}
        37.5% {top: 91%; left: 82%}
        43.75% {top: 73%; left: 92%;}
        50% { top: 47%; left: 94%;}
        
        56.25% {top: 23%; left: 92%;}
        62.5% {top: 6%; left: 82%;}
        68.75% {top: 12%; left: 70%;}
        75% { top: 48%; left:47%; }
        
        81.25% { top: 73%; left: 33%;}
        87.5% { top: 89%; left: 19%;}
        93.75% { top: 84%; left: 7%; } 
        100% { top: 48%;  left:1%;}
    }
    <div class="container">
      <div class="sphere"></div>
    </div>
    Login or Signup to reply.
  2. I have a detailed article on how to create such an animation (and more): https://css-tricks.com/advanced-css-animation-using-cubic-bezier/

    Here is the first code from the article:

    .ball {
      position: fixed;
      width: 50px;
      height: 50px;
      border-radius: 50%;
      background:radial-gradient(at 30% 30%,#0000,#000a) red;
      left: var(--x);
      top: var(--y);
      animation: x 1s, y 0.5s;
      animation-timing-function: cubic-bezier(.5, -800, .5, 800);
      animation-iteration-count: infinite;
    }
    
    @keyframes x {
      to {
        left: calc(var(--x) + 1px);
      }
    }
    
    @keyframes y {
      to {
        top: calc(var(--y) + 0.3px);
      }
    }
    <div class="ball" style="--x:300px;--y:100px;"></div>

    Another version with transform for better performance

    .ball {
      position: fixed;
      width: 50px;
      height: 50px;
      border-radius: 50%;
      background:radial-gradient(at 30% 30%,#0000,#000a) red;
      left: 300px;
      top: 100px;
      animation: x 1s, y 0.5s;
      animation-timing-function: cubic-bezier(.5, -800, .5, 800);
      animation-iteration-count: infinite;
    }
    
    @keyframes x {
      to {
        translate: 1px 0;
      }
    }
    
    @keyframes y {
      to {
        transform: translatey(0.3px);
      }
    }
    <div class="ball"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search