How to make a smooth curve/rotate in a CSS animation - css

I am trying to create a CSS animation to make a plane take off from a runway and then make a slight curve to the right as it gains altitude. To accomplish this, I believe I need to adjust scale, rotation and x/y coordinates in the keyframes. I've been playing around with it for a while but I can't figure out how to make it look natural. What's the best way to calculate the various values I will need to make a smooth curve up and to the right?
.container {
width:700px;
height:100%;
}
img {
max-width:100%;
}
.airplane {
position:absolute;
bottom:0;
animation: takeoff linear 2s forwards;
}
#keyframes takeoff {
0% {
transform: translate(0,0) rotate(0);
}
5% {
transform: translate(0,0) rotate(0) scale(.9);
}
10% {
transform: translate(0,0) rotate(0) scale(.9);
}
20% {
transform:translate(0,0) rotate(0) scale(0.85);
}
30% {
transform:translate(0,0) rotate(0) scale(0.80);
}
40% {
transform:translate(0,0) rotate(0) scale(0.75);
}
50% {
transform:translate(0,0) rotate(5deg) scale(0.5);
}
60% {
transform:translate(0,0) rotate(5deg) scale(0.45);
}
70% {
transform: translate(150px, -200px) rotate(10deg) scale(.4);
}
80% {
transform:translate(200px,-300px) rotate(20deg) scale(0.35);
}
90% {
transform:translate(250px,-400px) rotate(30deg) scale(0.3);
}
100% {
transform:translate(300px,-500px) rotate(30deg) scale(0.3);
}
}
<div class="container">
<img class="airplane" src=https://i.stack.imgur.com/DhHSc.png" />
</div>

You can probably consider an animation on the container to make it easier to handle:
.container {
position: absolute;
bottom: 0;
animation: takeoff-alt ease-in 1s 1s forwards;
}
img {
max-width:100%;
}
.airplane {
animation: takeoff linear 2s forwards;
}
#keyframes takeoff {
to {
transform: scale(0.1);
}
}
#keyframes takeoff-alt {
100% {
transform: rotate(30deg) translateY(-100%);
}
}
body {
overflow:hidden;
}
<div class="container">
<img class="airplane" src="https://i.stack.imgur.com/DhHSc.png" />
</div>

Related

Continuous bezier animation without inheriting easing-function on change

I have this animation, it is currently meant to be only fast at the start, however when it reaches 85% - 95% the cubic-Bezier should be continuously slow instead of starting from point 0 again and creating another fast start motion. Is there any way to add multiple cubic-Beziers for each animation state change or have the easing-function continuous from state to state?
.animate-winner {
animation: rollWinnerBait 9s cubic-bezier(0,.9,.76,.99) forwards normal 1
}
#keyframes rollWinnerBait {
0% {
transform: translateX(4988px)
}
85% {
transform: translateX(-80px)
}
95% {
transform: translateX(11px)
}
98% {
transform: translateX(-9px)
}
100% {
transform: translateX(0px)
}
}
Update the timing function inside the animation:
.animate-winner {
animation: rollWinnerBait 5s cubic-bezier(0, .9, .76, .99) forwards;
width:100px;
height:100px;
margin:5px;
background:red;
}
.animate-winner.new {
animation: rollWinnerBait-new 5s cubic-bezier(0, .9, .76, .99) forwards;
}
#keyframes rollWinnerBait {
0% {
transform: translateX(4988px)
}
85% {
transform: translateX(-80px);
}
95% {
transform: translateX(11px)
}
98% {
transform: translateX(-9px)
}
100% {
transform: translateX(0px);
}
}
#keyframes rollWinnerBait-new {
0% {
transform: translateX(4988px)
}
85% {
transform: translateX(-80px);
animation-timing-function:linear;
}
95% {
transform: translateX(11px)
}
98% {
transform: translateX(-9px)
}
100% {
transform: translateX(0px);
animation-timing-function:linear;
}
}
<div class="animate-winner"></div>
<div class="animate-winner new"></div>

Loop a CSS3 animation

I'm trying to loop a css3 animation between 3 elements, after the 3rd element ends, I want to restart the animation and so on...
Here's my code:
.oferta-prods.run-animation img{
animation-name:fadeIn;
animation-duration:4s;
animation-timing-function:ease-in-out;
opacity:0;
}
.oferta-prods.run-animation img:nth-child(1){animation-delay:0s;}
.oferta-prods.run-animation img:nth-child(2){animation-delay:4s;}
.oferta-prods.run-animation img:nth-child(3){animation-delay:8s;}
#keyframes fadeIn{
0%{
opacity:0;
}
10%{
opacity:1;
}
90%{
opacity:1;
}
100%{
opacity:0;
}
}
<div class="oferta-prods run-animation">
<img src="assets/House.svg">
<img src="assets/Car.svg">
<img src="assets/Beach.svg">
</div>
So, the idea is, element 1 starts animation then ends, element 2 starts animation then ends, then element 3 starts animation then ends. After this, I want to automatically begin a new cycle after the 3 elements end the animation.
Thank you
You can do this by defining 3 diferent animations with different execution timers.
Following my coding example bellow, we divide 100% / 3, and that gives us around 33%, meaning, that every image should run the animation for 33% of the animation total time.
Take a look at this example:
ody {
margin: 0;
padding: 0;
box-sizing: border-box;
height: 100vh;
}
.animation-wrapper div {
width: 20px;
height: 50px;
margin: 10px;
}
.animation-wrapper .anim-1 {
background-color: red;
animation: animation1 4s infinite ease-in-out;
}
.animation-wrapper .anim-2 {
background-color: blue;
animation: animation2 4s infinite ease-in-out;
}
.animation-wrapper .anim-3 {
background-color: green;
animation: animation3 4s infinite ease-in-out;
}
#keyframes animation1{
0%{
transform: translateX(0);
}
16.5%{
transform: translateX(20px);
}
33%{
transform: translateX(0);
}
100%{
transform: translateX(0);
}
}
#keyframes animation2{
0%{
transform: translateX(0);
}
33%{
transform: translateX(0);
}
49.5%{
transform: translateX(20px);
}
66%{
transform: translateX(0);
}
100%{
transform: translateX(0);
}
}
#keyframes animation3{
0%{
transform: translateX(0);
}
66%{
transform: translateX(0);
}
82.5%{
transform: translateX(20px);
}
99%{
transform: translateX(0);
}
100%{
transform: translateX(0);
}
}
<div class="animation-wrapper">
<div class="anim-1"></div>
<div class="anim-2"></div>
<div class="anim-3"></div>
</div>
One way is to use Javascript to restart the animation. It involves triggering a DOM reflow, so it may not be the best way on a heavy page.
const lastImage = document.querySelector(".oferta-prods.run-animation img:nth-child(3)");
lastImage.addEventListener("animationend", () => {
lastImage.parentNode.classList.remove("run-animation");
void lastImage.offsetWidth; // trigger DOM reflow
lastImage.parentNode.classList.add("run-animation");
});
.oferta-prods.run-animation img {
animation: 4s ease-in-out fadeIn;
opacity: 0;
}
.oferta-prods.run-animation img:nth-child(1) { animation-delay: 0s; }
.oferta-prods.run-animation img:nth-child(2) { animation-delay: 4s; }
.oferta-prods.run-animation img:nth-child(3) { animation-delay: 8s; }
#keyframes fadeIn {
0% { opacity: 0; }
10% { opacity: 1; }
90% { opacity: 1; }
100% {opacity: 0; }
}
<div class="oferta-prods run-animation">
<img src="assets/House.svg">
<img src="assets/Car.svg">
<img src="assets/Beach.svg">
</div>

How do I make a CSS Rotating Animation?

I'm trying to make a css rotation animation that has different speeds at different degree points.
Here is the animation I'm trying to make:
Here is a Pen of what I currently have and below is the code:
img {
width: 125px;
}
body {
text-align: center;
}
#loading {
-webkit-animation: slow 1.5s linear 1.5s, fast 1s linear 1s, slow2 1s linear 1s;
-webkit-animation-iteration-count: infinite;
}
#-webkit-keyframes slow {
from {
-webkit-transform: rotate(0deg)
}
to {
-webkit-transform: rotate(90deg)
}
}
#-webkit-keyframes fast {
from {
-webkit-transform: rotate(91deg)
}
to {
-webkit-transform: rotate(270deg)
}
}
#-webkit-keyframes slow2 {
from {
-webkit-transform: rotate(271deg)
}
to {
-webkit-transform: rotate(359deg)
}
}
<img id="loading" src="https://i.imgur.com/VpLRlbZ.png">
So, in the example you provided, the effect is only done by modifying the animation-timing-function css property.
Then you'll have only one animation
div {
width:100px;
height:100px;
background:red;
animation:rotate 3s infinite;
animation-timing-function: cubic-bezier(1,0,.5,1);
}
#-webkit-keyframes rotate {
from { -webkit-transform: rotate(0deg) }
to { -webkit-transform: rotate(360deg) }
}
<div></div>
You can find more informations here : https://callmenick.com/dev/level-up-animations-cubic-bezier/
But the point is, use only one animation and modify speed at different angles value modifying this animation-timing-function.
EDIT Added a closer cubic bezier timing function thanks to #SirExotic comment.
You can just divide the animation keyframes into several ones, and adjust the percentages of each to set the relative speeds:
The natural percentage for 90deg would be 25% . Any value higher than that will make this part slower
img {
width: 125px;
}
body {
text-align: center;
}
#loading {
animation: rotate 4s linear infinite;
}
#keyframes rotate {
0% {
transform: rotate(0deg)
}
40% {
transform: rotate(90deg)
}
60% {
transform: rotate(270deg)
}
100% {
transform: rotate(360deg)
}
}
<img id="loading" src="https://i.imgur.com/VpLRlbZ.png">

How can I assign different animation-speeds to different properties in a CSS3 animation?

I'm trying to make a ship moves from left to right and from top to bottom at the same time (it describes a straight downward line). I want to assign different speeds to the animation in the 'X' and 'Y' axis. I mean I want little ship to move slower when moving from left to right, and faster when moving from top to bottom, but I haven't been able to accomplish this because I don't know how to separate the speed of the different animated properties. I would highly appreciate any suggestion. Here is my code:
body {
overflow-x:hidden;
}
div {
width: 150px;
height: 150px;
top: 20px;
background-image: url('https://s-media-cache-ak0.pinimg.com/originals/c2/bb/ae/c2bbaed0207deef5775af9c01e1b31ba.jpg');
position: relative;
background-size: cover;
animation: mymove 5s linear infinite;
}
#-webkit-keyframes mymove {
0% {
left:-1%;
top:-1%;
transform: rotate(5deg)
}
20% {
transform: rotate(-5deg)
}
40%
{
transform: rotate(5deg)
}
60% {
transform: rotate(-5deg)
}
80%{
transform: rotate(5deg)
}
100% {
left:100%;
top:100%;
transform: rotate(-5deg)
}
}
<div></div>
Thanks in advance!
Try this updated keyframe
#-webkit-keyframes mymove {
0% {
left:-1%;
transform: rotate(5deg)
}
20% {
transform: rotate(-5deg)
}
40%
{
left:90%;
transform: rotate(5deg)
}
60% {
transform: rotate(90deg) translate(0px,0px)
}
80%{
transform: rotate(95deg) translate(210px,0px)
}
100% {
left:90%;
transform: rotate(90deg) translate(410px,0px)
}
}
Updated answer#1
ship will travel diagonally
#-webkit-keyframes mymove {
0% {
transform: translate(0px,0px) rotate(55deg)
}
10% {
transform: translate(100px,50px) rotate(60deg)
}
20% {
transform: translate(200px,100px) rotate(55deg)
}
30% {
transform: translate(300px,150px) rotate(60deg)
}
40% {
transform: translate(400px,200px) rotate(55deg)
}
50% {
transform: translate(500px,250px) rotate(60deg)
}
60% {
transform: translate(600px,300px) rotate(55deg)
}
70% {
transform: translate(700px,350px) rotate(60deg)
}
80% {
transform: translate(800px,400px) rotate(55deg)
}
90% {
transform: translate(900px,450px) rotate(60deg)
}
100% {
transform: translate(1000px,500px) rotate(55deg)
}
}

CSS3 Translate: Translate an element on an Ellipse path

I've been searching the answer for awhile but all I can see is translating an object in circular path. Is there a way to translate an element on an ellipse path given the semiminor and semimajor axis? Thanks alot!
the jfiddle of belows answer
css3
Have a look at this page, it explains mostly all you should know about translations with CSS3. Just as reminder: it is also possible to set keyframes you could use to definie your edge points of a spline you want to animate.
keyframes are explained here.
in your case it is a animation of two nested elements.
#1 for the picture or element you want to animate, where you define a X tranlate with ease
#2 and one as outer box for that #1 you animate the Y translate with.
if you arrange them clever in the same timescale but different ease in or out you can make your ellipse happen.
<style>
.viewport {
position:relative;
width:640px;
height:480px;
border:1px dashed #000;
}
.moveX {
position:absolute;
background:#f00;
height:2px;
width:480px;
top:240px;
left:0px;
-webkit-animation: mX 5s ease-in-out 0s infinite;
animation: mX 5s ease-in-out 0s infinite;
}
.moveY {
position:absolute;
width:480px;
height:100px; top:-50px;
border:1px solid #333;
-webkit-animation: mO 5s linear 0s infinite;
animation: mO 5s linear 0s infinite;
}
.elipsoid {
position:absolute;
background:url('http://placehold.it/100/00f/fff/&text=>°))><');
top: 0px;
left: 0px;
width: 100px;
height: 100px;
border-radius:50%;
}
#keyframes mO {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#-webkit-keyframes mO {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
#keyframes mX {
0% { transform: translateX(0px); }
50% { transform: translateX(160px); }
100% { transform: translateX(0px); }
}
#-webkit-keyframes mX {
0% { -webkit-transform: translateX(0px) }
50% { -webkit-transform: translateX(160px); }
100% { -webkit-transform: translateX(0px) }
}
</style>
<div class="viewport">
<span class="moveX">
<div class="moveY"><span class="elipsoid"></span></div>
</span>
</div>

Resources