Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to animate a car's wheels based on a moving and stopping car using CSS?

I'm trying to animate a car using CSS. I've managed to animate the wheels and the car.

The car moves in and stops and then moves off. this animation loops.

Now, I need to stop the wheels as well when then car stops. But I can't seem to achieve that.

This is what I have so far:

@keyframes wheel{
 0%{
   transform: rotate(0deg)
  }
  
    35% {
    transform: rotate(-90deg)
  }
  36%,
  56% {
    transform: rotate(-180deg)
  }
  
 100%{
   transform: rotate(-359deg)
  }
}

@keyframes moving {
  0% {
    right: -80em;
    animation-timing-function: ease-out;
  }
  35% {
    right: 0;
  }
  36%,
  56% {
    right: 0;
    animation-timing-function: ease-in;
  }
  100% {
    right: 120%;
  }
}

@keyframes stableWheel {
  from {transform: translateY(-.0em);}
  to {transform: translateY(-.0em);}
}


.car{
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 0 auto;
  position: relative;
  width: 600px;
  height:271px;
  overflow:hidden;
    animation: moving 10s linear -2s infinite;
}
.carbody{
  animation: carmove 3.1s infinite linear;
  background: url('https://i.stack.imgur.com/xWNOG.png') 0 0;
  background-size: cover;
  height: 271px;
  position: relative; 
  width: 600px;
  z-index: 125;
}



.weel{

  animation: wheel 0.7s infinite linear;
  background: url('https://i.stack.imgur.com/0Osjx.png') 0 0;
  height: 85px;
  position: absolute;
  top: 67%;
  width: 85px;
  z-index: 200;
}
.weel1{left: 85px;}
.weel2{left: 454px;}

/*animations*/
@keyframes carmove{
  0%{transform: translateY(0px);}
  25%{transform: translateY(1px)}
  29%{transform: translateY(2px)}
  33%{transform: translateY(3px)}
  47%{transform: translateY(0px)}
  58%{transform: translateY(1px)}
  62%{transform: translateY(2px)}
  66%{transform: translateY(3px)}
  75%{transform: translateY(1px)}
  100%{transform: translateY(0px)}
}




body {
  -webkit-animation: color-fade 10s infinite;
  -moz-animation: color-fade 10s infinite;
  animation: color-fade 10s infinite;
}

@-webkit-keyframes color-fade {
  0% { background: #9a5342; }
  25% { background: #fffc0c; }
  50% { background: #e46d00; }
  75% { background: #ff3506; }
  100% { background: #9a5342; }
}


.stopedWeel{
     animation: stableWheel .2s linear infinite alternate;
  
}
<div class="car">
  <div class="carbody"></div>
  <div class="weel weel1"></div>
  <div class="weel weel2"></div>
</div>

The wheels animation is this:

@keyframes wheel{
     0%{
       transform: rotate(0deg)
      }

        35% {
        transform: rotate(-90deg)
      }
      36%,
      56% {
        transform: rotate(-180deg)
      }

     100%{
       transform: rotate(-359deg)
      }
    }

if you run my code, the wheels are all jittery and lagging.

Could someone please advice on this?

like image 260
sam sexton Avatar asked Nov 18 '19 10:11

sam sexton


People also ask

Is it possible to animate an element using CSS?

CSS animations make it possible to animate transitions from one CSS style configuration to another. Animations consist of two components, a style describing the CSS animation and a set of keyframes that indicate the start and end states of the animation's style, as well as possible intermediate waypoints.


2 Answers

To make it easier, use the same duration for both animation then increase the angle of rotation to control the wheel. Simply make sure you get back to n*360deg at then end (not mandatory in this case since there is no cycle in the car movement)

I also optimized your code to use percentage value so you can easily control the whole car by simply adjusting the width of the main element:

.car{
  margin: 0 auto;
  position: relative;
  width: 400px;
  animation: moving 10s linear -2s infinite;
}
.car:before {
  content:"";
  display:block;
  animation: carmove 3.1s infinite linear;
  background: url('https://i.stack.imgur.com/xWNOG.png') center/cover;
  padding-top:45.25%;
}

.weel{
  animation: wheel 10s infinite -2s linear;
  background: url('https://i.stack.imgur.com/0Osjx.png') center/cover;
  position: absolute;
  bottom:0.8%;
  width: 14.15%;
}
.weel:before {
   content:"";
   display:block;
   padding-top:100%;
}
.weel1{left: 14.5%;}
.weel2{right: 10%;}

/*animations*/
@keyframes carmove{
  0%{transform: translateY(0px);}
  25%{transform: translateY(1px)}
  29%{transform: translateY(2px)}
  33%{transform: translateY(3px)}
  47%{transform: translateY(0px)}
  58%{transform: translateY(1px)}
  62%{transform: translateY(2px)}
  66%{transform: translateY(3px)}
  75%{transform: translateY(1px)}
  100%{transform: translateY(0px)}
}

@keyframes wheel{
 0%{
   transform: rotate(0deg)
  }
  35% {
    transform: rotate(-920deg)
  }
  36%,
  56% {
    transform: rotate(-920deg)
  }
 100%{
   transform: rotate(-1440deg)
  }
}

@keyframes moving {
  0% {
    right: -80em;
    animation-timing-function: ease-out;
  }
  35% {
    right: 0;
  }
  36%,
  56% {
    right: 0;
    animation-timing-function: ease-in;
  }
  100% {
    right: 120%;
  }
}

body {
  overflow:hidden;
}
<div class="car">
  <div class="weel weel1"></div>
  <div class="weel weel2"></div>
</div>

And a smaller car:

.car{
  margin: 0 auto;
  position: relative;
  width: 150px;
  animation: moving 10s linear -2s infinite;
}
.car:before {
  content:"";
  display:block;
  animation: carmove 3.1s infinite linear;
  background: url('https://i.stack.imgur.com/xWNOG.png') center/cover;
  padding-top:45.25%;
}

.weel{
  animation: wheel 10s infinite -2s linear;
  background: url('https://i.stack.imgur.com/0Osjx.png') center/cover;
  position: absolute;
  bottom:0.8%;
  width: 14.15%;
}
.weel:before {
   content:"";
   display:block;
   padding-top:100%;
}
.weel1{left: 14.5%;}
.weel2{right: 10%;}

/*animations*/
@keyframes carmove{
  0%{transform: translateY(0px);}
  25%{transform: translateY(1px)}
  29%{transform: translateY(2px)}
  33%{transform: translateY(3px)}
  47%{transform: translateY(0px)}
  58%{transform: translateY(1px)}
  62%{transform: translateY(2px)}
  66%{transform: translateY(3px)}
  75%{transform: translateY(1px)}
  100%{transform: translateY(0px)}
}

@keyframes wheel{
 0%{
   transform: rotate(0deg)
  }
  35% {
    transform: rotate(-920deg)
  }
  36%,
  56% {
    transform: rotate(-920deg)
  }
 100%{
   transform: rotate(-1440deg)
  }
}

@keyframes moving {
  0% {
    right: -80em;
    animation-timing-function: ease-out;
  }
  35% {
    right: 0;
  }
  36%,
  56% {
    right: 0;
    animation-timing-function: ease-in;
  }
  100% {
    right: 120%;
  }
}

body {
  overflow:hidden;
}
<div class="car">
  <div class="weel weel1"></div>
  <div class="weel weel2"></div>
</div>
like image 59
Temani Afif Avatar answered Oct 21 '22 23:10

Temani Afif


SVG Animation

Scenario

  1. The car appears on the right.
    Wheels spin

  2. Car stop in the middle of the road.
    Wheels do not spin

  3. The car rides again.
    Wheels spin

  4. Repetition of the whole cycle

Why did I write this primitive algorithm? Only in order to clearly follow it in the order of launching parallel and sequential animations.

Unlike CSS animations in SVG you can do without painstaking timing calculations.. And as it is written in the scenario so, and implement the start, stop animations

For example:

  • A pause follows after the end of the movement on the first leg

begin="an_move1.end"

  • Movement on the second section of the path will begin after pause

begin="an_pause.end"

See the code comments for more explanations.

body {
  -webkit-animation: color-fade 10s infinite;
  -moz-animation: color-fade 10s infinite;
  animation: color-fade 10s infinite;
}

@-webkit-keyframes color-fade {
  0% { background: #9a5342; }
  25% { background: #fffc0c; }
  50% { background: #e46d00; }
  75% { background: #ff3506; }
  100% { background: #9a5342; }
}

.container {
width:100%;
height:100%;
}
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
       width="1200" height="600" viewBox="0 0 600 800" preserveAspectRatio="xMinYMin meet">  
  <!-- Car -->
<g id="car" transform="translate(-2400,0)">
<image xlink:href="https://i.stack.imgur.com/xWNOG.png" width="100%" height="100%" />

 <g id="wheel_left" transform=" translate(85,430) scale(0.145)" >
   <image xlink:href="https://i.stack.imgur.com/0Osjx.png" width="100%" height="100%" >
     <!-- Left wheel rotation animation -->
 <animateTransform
     id="an_left"
	 attributeName="transform"
	 type="rotate"
	 begin="0s;6s;16s;26s;36s;46s;56s"
	 end="an_pause.begin"
	 values="
	 0 300 400;
	-360 300 400"
	 dur="1s"
	 repeatCount="indefinite"
 />
 </image>
 </g>  
     
 <g id="wheel_right" transform=" translate(455,430) scale(0.145)" >
 <image xlink:href="https://i.stack.imgur.com/0Osjx.png" width="100%" height="100%" > 
     <!-- Right wheel rotation animation -->
    <animateTransform
	  id="an_right"
	  attributeName="transform"
	  type="rotate"
	  begin="0s;6s;16s;26s;36s;46s;56s;66s;76s"
	  end="an_pause.begin"
	  values="
	   0 300 400;
	-360 300 400"
	  dur="1s"
	  repeatCount="indefinite"
	/>
 </image>
 </g>
</g>   
<!-- Animation of a car moving to a stop -->
 <animateTransform
   id="an_move1"
   xlink:href="#car"
   attributeName="transform"
   type="translate"
   begin="0s;an_move2.end"
   values="2400;800"
   dur="4s"
   fill="freeze"
   repeatCount="1"
 />  
 <!-- Car  move  pause  -->
 <animateTransform
   id="an_pause"
   xlink:href="#car"
   attributeName="transform"
   type="translate"
   begin="an_move1.end"
   values="800"
   dur="2s"
   fill="freeze"
   repeatCount="1"
 /> 
 <!-- Animation of a car moving after a stop -->
  <animateTransform
   id="an_move2"
   xlink:href="#car"
   attributeName="transform"
   type="translate"
   begin="an_pause.end"
   values="800;-600"
   dur="4s"
   fill="freeze"
   repeatCount="1"
 /> 

</svg>	 
</div>
like image 33
Alexandr_TT Avatar answered Oct 22 '22 00:10

Alexandr_TT