Reputation: 193
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.sstatic.net/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.sstatic.net/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?
Upvotes: 10
Views: 4725
Reputation: 272901
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.sstatic.net/xWNOG.png') center/cover;
padding-top:45.25%;
}
.weel{
animation: wheel 10s infinite -2s linear;
background: url('https://i.sstatic.net/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.sstatic.net/xWNOG.png') center/cover;
padding-top:45.25%;
}
.weel{
animation: wheel 10s infinite -2s linear;
background: url('https://i.sstatic.net/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>
Upvotes: 16
Reputation: 14545
Scenario
The car appears on the right.
Wheels spin
Car stop in the middle of the road.
Wheels do not spin
The car rides again.
Wheels spin
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:
begin="an_move1.end"
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.sstatic.net/xWNOG.png" width="100%" height="100%" />
<g id="wheel_left" transform=" translate(85,430) scale(0.145)" >
<image xlink:href="https://i.sstatic.net/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.sstatic.net/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>
Upvotes: 4
Reputation: 1785
At the middle of the view screen both car and wheel animations should be stopped few seconds. So wheel animation should be same as car's animation.
.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;
}
Updated wheel styles should be looked like below.
.weel{
/*animation: wheel 0.7s infinite linear;*/
animation: wheel 10s linear -2s infinite;
background: url('https://i.sstatic.net/0Osjx.png') 0 0;
height: 85px;
position: absolute;
top: 67%;
width: 85px;
z-index: 200;
}
If you run the code now you can see wheel and car animate works simultaneously. But there you can find a difference between car speed and wheel speed and wheel should be stopped until car body moves again. For fix that speed and wheel issues, you need to increase keyframe values while keep middle two keyframe values equal.
@keyframes wheel{
0%{
transform: rotate(0deg)
}
35% {
transform: rotate(-500deg)
}
36%,
56% {
transform: rotate(-500deg)
}
100%{
transform: rotate(-1000deg)
}
}
This Js Fiddle link shows the live animation.
Upvotes: 1