CSS3 Animation Parabola
Today we will talk about CSS3 animation. The goal is to make a block move in a parabola. The main CSS3 properties used include animation, transform, @keyframes, transition, etc.
We first create an HTML file, test.html:
<!DOCTYPE html><html><head> <link rel="stylesheet" type="text/css" href="animation.css"/></head><body><div class="item"></div> </body></html>
Because the animation attribute can create animations through @keyframes rules, then if we To make a parabola, try simply defining the positions of several phases.
Write our CSS file, animation.css:
.item { width:50px; height: 50px; display: inline-block; position: absolute; top: 100px; background-color: red; }div { animation: example 3s linear 1s 1; -webkit-animation: example 3s linear 1s 1; -moz-animation: example 3s linear 1s 1; }@-moz-keyframes example { 0% { transform: translate3d(0px, 0, 0); } 25% { transform: translate3d(100px, -40px, 0); } 50% { transform: translate3d(200px, -56px, 0); } 75% { transform: translate3d(300px, -68px, 0); } 100% { transform: translate3d(400px, -80px, 0); } } @-webkit-keyframes example { 0% { transform: translate3d(0px, 0, 0); } 25% { transform: translate3d(100px, -40px, 0); } 50% { transform: translate3d(200px, -56px, 0); } 75% { transform: translate3d(300px, -68px, 0); } 100% { transform: translate3d(400px, -80px, 0); } }
Run it, it can only be described as horrible. I will definitely be criticized for writing this. This is simply a scam.
First of all, this method is not a parabola, it is just a few line segments put together. If the percentage is made thinner, it can be similar to a parabola, but it greatly increases the coding time, and it is only simulating a parabola. It is better to use The formula of a parabola is used to calculate the coordinates of each point through JavaScript.
This version is a purely negative teaching material.
Reanalyze this problem. A parabola is actually a uniform motion in the horizontal direction and a uniform acceleration in the vertical direction. Then we can put a div outside the item. The inner one controls the horizontal movement and uses linear for the speed curve. The outer one controls the vertical movement and uses ease-in for the speed curve.
test.html:
<!DOCTYPE html><html><head> <link rel="stylesheet" type="text/css" href="animation.css"/></head><body><div class="wraper"><div class="item"></div></div></body></html>
Then animation.css:
.item, .item2 { width:50px; height: 50px; display: inline-block; position: absolute; top: 100px; left: 0px; background-color: red; }.wraper { animation: vertical-animation 3s ease-in 1s 1; -webkit-animation: vertical-animation 3s ease-in 1s 1; -moz-animation: vertical-animation 3s ease-in 1s 1; }.wraper .item { animation: hor-animation 3s linear 1s 1; -webkit-animation: hor-animation 3s linear 1s 1; -moz-animation: hor-animation 3s linear 1s 1; }@-moz-keyframes hor-animation { 0% { transform: translateX(0px); } 100% { transform: translateX(400px); } } @-webkit-keyframes hor-animation { 0% { transform: translateX(0px); } 100% { transform: translateX(400px); }}@-moz-keyframes vertical-animation { 0% { transform: translateY(0px); } 100% { transform: translateY(400px); } } @-webkit-keyframes vertical-animation { 0% { transform: translateY(0px); } 100% { transform: translateY(400px); } }
ok, run it, it looks like a parabola.
The method just now requires adding an extra dom element. Is there any way not to add it? Of course, you can use the transition attribute for postion:absolute to control the changes of top and left respectively. The time curve of top change is ease-in, and the time curve of left change is linear.
We add one more item2 to do this:
test.html:
<!DOCTYPE html><html><head> <link rel="stylesheet" type="text/css" href="animation.css"/></head><body><div class="wraper"><div class="item"></div></div><div class="item2"></div><script type="text/javascript" src="animation.js"></script></body></html>
animation.css:
.item, .item2 { width:50px; height: 50px; display: inline-block; position: absolute; top: 100px; left: 0px; background-color: red; }.wraper { animation: vertical-animation 3s ease-in 1s 1; -webkit-animation: vertical-animation 3s ease-in 1s 1; -moz-animation: vertical-animation 3s ease-in 1s 1; }.wraper .item { animation: hor-animation 3s linear 1s 1; -webkit-animation: hor-animation 3s linear 1s 1; -moz-animation: hor-animation 3s linear 1s 1; }@-moz-keyframes hor-animation { 0% { transform: translateX(0px); } 100% { transform: translateX(400px); } } @-webkit-keyframes hor-animation { 0% { transform: translateX(0px); } 100% { transform: translateX(400px); }}@-moz-keyframes vertical-animation { 0% { transform: translateY(0px); } 100% { transform: translateY(400px); } } @-webkit-keyframes vertical-animation { 0% { transform: translateY(0px); } 100% { transform: translateY(400px); } }.item2 { top: 150px; left: 0px; transition: top 3s ease-in 1s, left 3s linear 1s; -webkit-transition: top 3s ease-in 1s, left 3s linear 1s; -moz-transition: top 3s ease-in 1s, left 3s linear 1s; }
Here we need to add one more javascript file To control the changes of item2 top and left attributes.
animation.js:
window.onload = function(){ var item2 = document.querySelector(".item2"); item2.style.top = "550px"; item2.style.left = "400px";}
ok, run it, it will also be a parabolic motion.
First of all, the movement of item and item2 is inconsistent, item always moves before item2.
Is it a page loading problem? Let’s make a slight change so that they move at the same time as much as possible.
In css, let the item be paused first.
.wraper { animation: vertical-animation 3s ease-in 1s 1; -webkit-animation: vertical-animation 3s ease-in 1s 1; -moz-animation: vertical-animation 3s ease-in 1s 1; animation-play-state:paused; -webkit-animation-play-state:paused; }.wraper .item { animation: hor-animation 3s linear 1s 1; -webkit-animation: hor-animation 3s linear 1s 1; -moz-animation: hor-animation 3s linear 1s 1; animation-play-state:paused; -webkit-animation-play-state:paused; }
Here, by adding animation-play-state:paused, the animation will be paused at the beginning.
Control the running of animation in javascript, and change the top and left values of item2.
window.onload = function(){ var item2 = document.querySelector(".item2"), item = document.querySelector(".item"), warper = document.querySelector(".warper"); item2.style.top = "550px"; item2.style.left = "400px"; item.style.animationPlayState = "running"; item.style.webkitAnimationPlayState = "running"; warper.style.animationPlayState = "running"; warper.style.webkitAnimationPlayState = "running";}
Okay, run it again, the item will move first. And I feel that item2 is a bit stuck.
Here we finally get to the point. Let’s open Chrome’s debugging tool and observe the paint time-consuming of the two solutions.
The first is the transition version, which is item2.
As you can see, the green part spends about 96ms on painting.
Then let’s look at the animation version, which is item:
Wow, the time spent on painting is only 0.68ms.
After further searching on the Internet, it turns out that using translate will trigger hardware acceleration. Greatly shorten the painting time. The transition does not take advantage of hardware acceleration, and will trigger multiple repaints, so it will feel a bit stuck and not smooth enough.
First of all, when we analyze a problem, we should not just see the surface behavior of things and not simply simulate the surface, but should think about the essence. Just like making a parabola, you can't just simulate the motion trajectory, but you should also understand the essence of parabola motion.
Also, I can’t help but sigh, CSS3 is really broad and profound. I would also like to thank a brother from Tencent ISUX for his guidance.
http://blog.bingo929.com/transform-translate3d-translatez-transition-gpu-hardware-acceleration.html
http://www.admin10000. com/document/4339.html