Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rotate around object smoothly in CSS

I have two images moving around a DOM element. But their rotation is wrong and the movement is not smooth.

My fiddle

#mainPage {
  width: 400px;
  height: 165px;
  margin: 10% auto;
}

#mainPage>p {
  text-align: center;
}

.bicycle {
  width: 48px;
  height: 30px;
  background: red;
}

#bicycleOriginal {
  animation: moveBicycleOriginal 20s infinite;
}

#bicycleFlipped {
  animation: moveBicycleFlipped 20s infinite;
}

#mainTxt {
  letter-spacing: 7px;
  font-size: 30px;
  margin-bottom: 30px;
}

@keyframes moveBicycleOriginal {
  from {
    transform: translate(0, 0);
  }
  1% {
    transform: translate(0, 0) rotate(0deg);
  }
  25% {
    transform: translate(350px, 0);
  }
  26% {
    transform: translate(350px, 0) rotate(90deg);
  }
  50% {
    transform: translate(350px, 150px);
  }
  51% {
    transform: translate(350px, 150px) rotate(180deg);
  }
  75% {
    transform: translate(0, 150px);
  }
  76% {
    transform: translate(0, 150px) rotate(270deg);
  }
  to {
    transform: translate(0, 0);
  }
}

@keyframes moveBicycleFlipped {
  from {
    transform: translate(350px, 0);
  }
  1% {
    transform: translate(350px, 0) rotate(0deg);
  }
  25% {
    transform: translate(0, 0);
  }
  26% {
    transform: translate(0, 0) rotate(90deg);
  }
  50% {
    transform: translate(0, -150px);
  }
  51% {
    transform: translate(0, -150px) rotate(180deg);
  }
  75% {
    transform: translate(350px, -150px);
  }
  76% {
    transform: translate(350px, -150px) rotate(270deg);
  }
  to {
    transform: translate(350px, 0);
  }
}
<div id="mainPage">
  <div class="bicycle" id="bicycleOriginal"></div>

  <p class="txt" id="mainTxt">DRAHTESEL</p>

  <div class="bicycle" id="bicycleFlipped"></div>
</div>

So what I want is something like this

Rotation

After passing the first keyframe the boxes get into a wrong rotation. Also they don't move smoothly, the get faster in the middle and slower when reaching the end.

Could someone help me with the keyframes?

like image 782
peterHasemann Avatar asked Dec 23 '22 09:12

peterHasemann


2 Answers

You need to always keep the rotate defined within the transform because each transform will override the previous one and removing the rotation means rotate(0).

And to make the animation more accurate, the last state should be similar to the first state to avoid the jump when restarting the animation. So you should go to 360deg of rotation which is equivalent to 0deg. (like you did with the translation where you come back to the initial value).

Then you may adjust the animation-timing-function to control the animation progress if needed.

#mainPage {
  width: 400px;
  height: 165px;
  margin: 10% auto;
}

#mainPage>p {
  text-align: center;
}

.bicycle {
  width: 48px;
  height: 30px;
  background: red;
}

#bicycleOriginal {
  animation: moveBicycleOriginal 20s infinite;
}

#bicycleFlipped {
  animation: moveBicycleFlipped 20s infinite;
}

#mainTxt {
  letter-spacing: 7px;
  font-size: 30px;
  margin-bottom: 30px;
}

@keyframes moveBicycleOriginal {
  from {
    transform: translate(0, 0) rotate(0deg);
  }
  25% {
    transform: translate(350px, 0) rotate(0deg);
  }
  26% {
    transform: translate(350px, 0) rotate(90deg);
  }
  50% {
    transform: translate(350px, 150px) rotate(90deg);
  }
  51% {
    transform: translate(350px, 150px) rotate(180deg);
  }
  75% {
    transform: translate(0, 150px) rotate(180deg);
  }
  76% {
    transform: translate(0, 150px) rotate(270deg);
  }
  98% {
    transform: translate(0, 0) rotate(270deg);
  }
  to {
    transform: translate(0, 0) rotate(360deg);
  }
}

@keyframes moveBicycleFlipped {
  from {
    transform: translate(350px, 0) rotate(0deg);
  }
  25% {
    transform: translate(0, 0) rotate(0deg);
  }
  26% {
    transform: translate(0, 0) rotate(90deg);
  }
  50% {
    transform: translate(0, -150px) rotate(90deg);
  }
  51% {
    transform: translate(0, -150px) rotate(180deg);
  }
  75% {
    transform: translate(350px, -150px) rotate(180deg);
  }
  76% {
    transform: translate(350px, -150px) rotate(270deg);
  }
  97% {
    transform: translate(350px, 0) rotate(270deg);
  }
  to {
    transform: translate(350px, 0) rotate(360deg);
  }
}
<div id="mainPage">
  <div class="bicycle" id="bicycleOriginal"></div>

  <p class="txt" id="mainTxt">DRAHTESEL</p>

  <div class="bicycle" id="bicycleFlipped"></div>
</div>
like image 164
Temani Afif Avatar answered Jan 05 '23 11:01

Temani Afif


The speed slowing/speeding is because of the animationTiming (default ease), that should be 'linear'.

The reason the animation is incorrect, it because you unset the rotation. This might come unexpected, you control transformation with css transform. You also control rotation with transform.

#example{
    transform: rotate(10deg)
}
#example.changed{
    transform: translateX(100px);
}

In this snippet, when you add the class changed you redefine transform, telling it to forget rotate and set translateX. In this example, to keep them both:

#example.changed{
    transform: rotate(10deg) translateX(100px);
}
like image 25
Martijn Avatar answered Jan 05 '23 11:01

Martijn