We have introduced speed animation, transparency animation, multi-object motion and arbitrary value changes before, and we areJavascript animation effect (II)In this article, we have encapsulated a simple plug-in prototype. Next, we will further expand the previous animation effects and try to make our framework more practical. Here we also need to understand two movements, one is chain movement and the other is simultaneous movement. The difference between them is: chain movement refers to movement one after another (one movement completes the next movement immediately); while simultaneous movement refers to all movements being performed simultaneously. Here, how should we achieve it?
1. Chain motion
In the previous effects, we can already change any value accordingly. How should we add an animation after an animation?
Idea: Can we pass a function into the parameters, and execute the subsequent function (effect) immediately after an effect is completed. The function can be the desired animation effect
Implementation: Pass a parameter fn in function startMove(obj, attr, iTarget) to represent a function. At this time, we also need to modify the timer to add a judgment if(fn){fn(); }, execute the fn function when there is a fn function, and clear the timer when there is no fn function. In this way, our function should also change accordingly, the code is as follows:
= function() { var Li = ('li1'); = function() { startMove(Li, 'width', 400, function() { startMove(Li, 'height', 200, function() { startMove(Li, 'opacity', 100); }); }); }; = function() { startMove(Li, 'opacity', 30, function() { startMove(Li, 'height', 100, function() { startMove(Li, 'width', 200); }); }); }; };
So we get the following code for chain motion:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Chain motion</title> <style type="text/css"> body,ul,li{ margin: 0px; padding: 0px; } ul,li{ list-style: none; } ul li{ width: 200px; height: 100px; background: yellow; margin-bottom: 20px; border: 4px solid #000; filter:alpha(opacity:30); opacity:0.3; } </style> </head> <body> <ul> <li ></li> </ul> <script type="text/javascript"> = function(){ var Li = ('li1'); = function(){ startMove(Li,'width',400,function(){ startMove(Li,'height',200,function(){ startMove(Li,'opacity',100); }); }); }; = function(){ startMove(Li,'opacity',30,function(){ startMove(Li,'height',100,function(){ startMove(Li,'width',200); }); }); }; }; function startMove(obj,attr,iTarget,fn){ clearInterval(); = setInterval(function(){ var icur = 0; if(attr == 'opacity'){ icur = (parseFloat(getStyle(obj,attr))*100); }else{ icur = parseInt(getStyle(obj,attr)); } var speed = (iTarget - icur)/10; speed = speed>0?(speed):(speed); if(iTarget == icur){ clearInterval(); if(fn){ fn(); } } else{ if(attr == 'opacity'){ = 'alpha(opacity:'+(icur+speed)+')'; = (icur+speed)/100; } else{ [attr] = icur+speed+'px'; } } },30) } function getStyle(obj,attr){ if(){ return [attr]; } else{ return getComputedStyle(obj,false)[attr]; } } </script> </body> </html>
2. Exercise at the same time
Speaking of simultaneous motion, you may find it very simple. Just adding two different starMove() functions at the same time after the onmouseover event can solve it (wrong idea!). In fact, this is not the case. When there are multiple effects, we see the last effect added. That is to say, we want to change the width and height at the same time (height is behind), and the effect we get is to change only the height, and the width does not change. Should we continue to pass parameters here? From the perspective of chain motion, the effect of passing parameters can only be added to the function to obtain continuous animation effects.
Idea: Can we use JSON method to change multiple animation effects at the same time?
Implementation: Merge attr and iTarget in function startMove(obj, attr, iTarget, fn) into one parameter: json, we use the for/in method to traverse the data in json, for example:
var json = {"a":12,"b":21}; for(var attr in json){ alert(json);//The results are: a, b alert(json[attr]);//The results are: 12, 21}
According to this method, we change the previous code in turn: add the code after the timer function: for(var attr in json) {...}, and modify the iTarget inside to json[attr], and then modify the function to:
= function() { var Li = ('li1'); = function() { startMove(Li, { width: 400, height: 200, opacity: 100 }); }; = function() { startMove(Li, { width: 200, height: 100, opacity: 30 }); }; };
At this time, we can almost get the effect we want, but we still checked a little bit from our final effect. For example, we change the width in starMove in the onmouseover event to 202, and then execute our code, and we will find that the final height is not 200px, and the opacity is not 100, as shown in the figure:
This is very embarrassing. Didn’t our results be quite good before? Let's go back to our JS code to analyze the structure and think that the most likely error is in the starMove function. We found that the meaning of this code is a bit difficult to understand:
if(json[attr] == icur) { clearInterval(); if(fn) { fn(); } }
We do not know whether all movements stop when all movements reach the end or when only one movement reaches the end. However, through our previous operations, the actual result we can know is that when only one movement reaches the end value, all movements stop (there are still movements that have not been completed at this time). How should we operate?
Idea: We can assume that a parameter flag and assign it to true. Before executing clearInterval(); operation, we first judge if(json[attr] != iicur) { flag = false;}, and then execute the previous statement in else, and then execute the following statement if(flag = true) {clearInterval(); if(fn) {fn();}}, so that we can get the complete code of simultaneous motion as follows:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Chain motion</title> <style type="text/css"> body,ul,li{ margin: 0px; padding: 0px; } ul,li{ list-style: none; } ul li{ width: 200px; height: 100px; background: yellow; margin-bottom: 20px; border: 4px solid #000; filter:alpha(opacity:30); opacity:0.3; } </style> </head> <body> <ul> <li ></li> </ul> <script type="text/javascript"> = function(){ var Li = ('li1'); = function(){ startMove(Li,{width:202,height:200,opacity:100}); }; = function(){ startMove(Li,{width:200,height:100,opacity:30}); }; }; function getStyle(obj, attr) { if() { return [attr]; } else { return getComputedStyle(obj, false)[attr]; } } function startMove(obj, json, fn) { //Define the benchmark var flag = true; //Assumed clearInterval(); = setInterval(function() { for(var attr in json) { var icur = 0; if(attr == 'opacity') { icur = (parseFloat(getStyle(obj, attr)) * 100); } else { icur = parseInt(getStyle(obj, attr)); } var speed = (json[attr] - icur) / 10; speed = speed > 0 ? (speed) : (speed); if(json[attr] != icur) { flag = false; } if(attr == 'opacity') {//Judge whether it is opacity = 'alpha(opacity:' + (icur + speed) + ')'; = (icur + speed) / 100; } else { [attr] = icur + speed + 'px'; } if(flag){ clearInterval(); if(fn){ fn(); } } } }, 30) } </script> </body> </html>
In this way, our simultaneous motion animation effect will be realized. Do you find it amazing here?
Here we have completed the encapsulation of a simple sports plug-in. We will explain the code inside and save it as a file. The code is as follows:
/* * Simple motion frame * Author: foodoir * This framework is for reference only! ! ! * * See blog post for how to use */ function getStyle(obj, attr) { if() { return [attr]; } else { return getComputedStyle(obj, false)[attr]; } } function startMove(obj, json, fn) { clearInterval(); //Clear the timer to avoid repeated generation of multiple timers = setInterval(function() { var flag = true; //Suppose that all the movements have been completed at the beginning for(var attr in json) { //Transfer json var icur = null; //1.Judge type if(attr == 'opacity') { icur = (parseFloat(getStyle(obj, attr)) * 100); } else { icur = parseInt(getStyle(obj, attr)); } //2. Calculate the speed var speed = (json[attr] - icur) / 5; speed = speed > 0 ? (speed) : (speed); //3. Detection stops if(icur != json[attr]) { flag = false; } if(attr == 'opacity') { = 'alpha(opacity:' + (icur + speed) + ')'; = (icur + speed) / 100; } else { [attr] = icur + speed + 'px'; } } if(flag) { // Clear the timer when all movements are completed clearInterval(); if(fn) { fn(); } } }, 30); }
Later, we will introduce using our own framework to achieve multiple animation effects and compare them with the animation effects in jquery.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.