Uniform motion
Motion is a basic operation for javascript animation. Motion can be achieved through the Transition and animation properties of CSS3. (More on this later in CSS3). But javascript motion is essential for more fine-grained manipulation.
Simple movement
Moving an element around the page is as simple as setting a timer and changing the left and top values of the positioned element
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>* {padding: 0;
margin: 0;
}
#box{
position: relative;
width: 200px;
height: 200px;
background-color: red;
left: -200px;
}
#box span{
position: absolute;
width: 40px;
height: 60px;
background-color: # 000;
color: #fff;
right: -40px;
top: 50%;
margin-top: -30px;
line-height: 60px;
text-align: center;
}
</style>
</head>
<body>
<span>open</span>
<div id="box">
</div>
<script>
window.onload = function () {
var oDiv = document.getElementById('box');
oDiv.onmouseover = function () {
setInterval(function () {
oDiv.style.left = oDiv.offsetLeft + 10 + 'px';
},30)}}</script>
</body>
</html>
Copy the code
View the effect:
It will be found that the number of times the mouse suspension, the timer will add up. And the games will go on and on. That’s not what we want. It comes down to timers and the handling of thresholds.
Timer Management
The above code does not manage timers. When the element is in the process of movement, the suspension button for many times will start the timer, so as to speed up the movement
Two timer management modes are available
-
Delete the old timer before starting the new timer
-
When the timer is not stopped, a new timer cannot be started
Note: Since the return value of the timer is a non-zero integer when it is started, you can determine whether to use the return statement by judging its return value
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
padding: 0;
margin: 0;
}
#box {
position: relative;
width: 200px;
height: 200px;
background-color: red;
left: -200px;
}
#box span {
position: absolute;
width: 40px;
height: 60px;
background-color: # 000;
color: #fff;
right: -40px;
top: 50%;
margin-top: -30px;
line-height: 60px;
text-align: center;
}
</style>
</head>
<body>
<div id="box">
<span>open</span>
</div>
<script>
window.onload = function() {
var oDiv = document.getElementById('box');
var timer = null;
oDiv.onmouseover = function() {
//1. Clear the timer before starting it
// clearInterval(timer);
//2. When the timer is not stopped, a new timer cannot be started
if(timer) return;
timer = setInterval(function() {
if (oDiv.offsetLeft == 500) {
clearInterval(timer);
} else {
oDiv.style.left = oDiv.offsetLeft + 5 + 'px'; }},30)}}</script>
</body>
</html>
Copy the code
Share the results
Create an effect similar to the “Share to” sidebar
<! DOCTYPEhtml>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
#box {
position: relative;
width: 200px;
height: 200px;
background-color: red;
left: -200px;
}
#box span {
position: absolute;
width: 40px;
height: 60px;
background-color: # 000;
color: #fff;
right: -40px;
top: 50%;
margin-top: -30px;
line-height: 60px;
text-align: center;
}
</style>
</head>
<body>
<div id="box">
<span>open</span>
</div>
<script type="text/javascript">
window.onload = function (){
var oDiv = document.getElementById('box');
oDiv.onmouseover = function (){
oDiv.style.left = 0 + 'px';
}
oDiv.onmouseout = function (){
oDiv.style.left = -200 + 'px'; }}</script>
</body>
</html>
Copy the code
Effect display:
Move in and move out effect
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
padding: 0;
margin: 0;
}
#box {
position: relative;
width: 200px;
height: 200px;
background-color: red;
left: -200px;
}
#box span {
position: absolute;
width: 40px;
height: 60px;
background-color: # 000;
color: #fff;
right: -40px;
top: 50%;
margin-top: -30px;
line-height: 60px;
text-align: center;
}
</style>
</head>
<body>
<div id="box">
<span>open</span>
</div>
<script>
window.onload = function() {
var oDiv = document.getElementById('box');
var timer = null;
oDiv.onmouseover = function() {
// Clear the timer before starting the timer
clearInterval(timer);
timer = setInterval(function() {
// Set the boundary and clear the timer
if (oDiv.offsetLeft === 0) {
clearInterval(timer);
} else {
oDiv.style.left = oDiv.offsetLeft + 5 + 'px'; }},30)
}
oDiv.onmouseout = function() {
// Clear the timer before starting the timer
clearInterval(timer);
timer = setInterval(function() {
console.log(oDiv.offsetLeft);
// Set the boundary and clear the timer
if (oDiv.offsetLeft === -200) {
clearInterval(timer);
} else {
oDiv.style.left = oDiv.offsetLeft - 5 + 'px'; }},30)}}</script>
</body>
</html>
Copy the code
Movement function
From the above code, we can see that there is a lot of repetitive code in the movement part, and it is more appropriate to encapsulate the movement as a function with parameters
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>* {padding: 0;
margin: 0;
}
#box{
position: relative;
width: 200px;
height: 200px;
background-color: red;
left: -200px;
}
#box span{
position: absolute;
width: 40px;
height: 60px;
background-color: # 000;
color: #fff;
right: -40px;
top: 50%;
margin-top: -30px;
line-height: 60px;
text-align: center;
}
</style>
</head>
<body>
<div id="box">
<span>open</span>
</div>
<script>
window.onload = function () {
var oDiv = document.getElementById('box');
oDiv.onmouseover = function () {
// Uniform motion begins
startMove(this.0)
}
oDiv.onmouseout = function () {
// Uniform motion begins
startMove(this, -200)}}var timer = null,speed = 0;
/ * * *@param {Object} ODiv current target object *@param {Object} Target Indicates the target position of the movement */
function startMove(oDiv,target) {
// Clear the timer before starting the timer
clearInterval(timer);
timer = setInterval(function () {
// We want the box to be able to move forward as well as backward, so we need to have both positive and negative steps
// The target value is positive if greater than the current value, and negative if less than the current value
speed = target > oDiv.offsetLeft ? 10 : -10;
// Set the boundary and clear the timer
if(oDiv.offsetLeft === target){
clearInterval(timer);
}else{
oDiv.style.left = oDiv.offsetLeft + speed + 'px'; }},30)}</script>
</body>
</html>
Copy the code
Effect display:
Slow motion
What is slow motion? For example, when a train enters a station, its speed changes from fast to slow, while when the train leaves the station, its speed changes from slow to fast.
Slow animation formula: speed = (end value – start value) * slow coefficient.
The number between 0 and 1.
Basic slow animation
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
padding: 0;
margin: 0;
}
#box {
position: relative;
width: 200px;
height: 200px;
background-color: red;
left: -200px;
}
#box span {
position: absolute;
width: 40px;
height: 60px;
background-color: # 000;
color: #fff;
right: -40px;
top: 50%;
margin-top: -30px;
line-height: 60px;
text-align: center;
}
</style>
</head>
<body>
<div id="box">
<span>open</span>
</div>
<script>
window.onload = function() {
var oDiv = document.getElementById('box');
var timer = null,target = 0,target1 = -200;
oDiv.onmouseover = function() {
clearInterval(timer);
timer = setInterval(function() {
speed = (target-oDiv.offsetLeft) / 20;
if (oDiv.offsetLeft == target) {
clearInterval(timer);
} else {
oDiv.style.left = oDiv.offsetLeft + speed + 'px'; }},30)
}
oDiv.onmouseout= function() {
clearInterval(timer);
timer = setInterval(function() {
speed = (target1-oDiv.offsetLeft) / 20;
if (oDiv.offsetLeft == target1) {
clearInterval(timer);
} else {
oDiv.style.left = oDiv.offsetLeft + speed + 'px'; }},30)}}</script>
</body>
</html>
Copy the code
Slow motion function
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
padding: 0;
margin: 0;
}
#box {
position: relative;
width: 200px;
height: 200px;
background-color: red;
left: -200px;
}
#box span {
position: absolute;
width: 40px;
height: 60px;
background-color: # 000;
color: #fff;
right: -40px;
top: 50%;
margin-top: -30px;
line-height: 60px;
text-align: center;
}
</style>
</head>
<body>
<div id="box">
<span>open</span>
</div>
<script>
window.onload = function() {
// Get the label
var oDiv = document.getElementById('box');
// Timer variable is set globally, to be dealt with later
var timer = null;
oDiv.onmouseover = function() {
slowMove(this.0);
}
//
oDiv.onmouseout= function() {
slowMove(this, -200);
}
function slowMove(obj,target){
clearInterval(timer);
timer = setInterval(function() {
speed = (target-obj.offsetLeft) / 20;
// If the velocity is greater than 0, it is to the right, rounded up. If the velocity is less than 0, you go left and round down
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if (obj.offsetLeft == target) {
clearInterval(timer);
} else {
obj.style.left = obj.offsetLeft + speed + 'px'; }},30)}}</script>
</body>
</html>
Copy the code
Transparency animation
Opacity is a special style, because Internet Explorer 8 does not support opacity, which can only be written as filter: alpha(opacity= opacity).
If the transparency moves, the motion function needs to be repackaged
The fading
The code is as follows:
<! DOCTYPEhtml>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#box{
width: 200px;
height: 200px;
background-color: red;
opacity: 0.3;
filter: alpha(opactity:30);
}
</style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
window.onload = function (){
var box = document.getElementById('box');
box.onmouseover = function (){
opacityAnimation(box,100);
}
box.onmouseout = function (){
opacityAnimation(box,30);
}
var alpha = 30,timer = null,speed = 0;
function opacityAnimation(ele,target){
clearInterval(timer);
timer = setInterval(function(){
// If the target value is greater than the currently changing value, it is represented as true and transparency is increasing, and vice versa
speed = target > alpha ? 10 : -10;
// The current change value equals the target value, clear the timer
if(alpha == target){
clearInterval(timer);
}else{
// Otherwise, transparency changes
alpha+=speed;
ele.style.filter = 'alpha(opactity:'+alpha+') ';
ele.style.opacity = alpha / 100; }},30)}}</script>
</body>
</html>
Copy the code
Different from the movement of the object, the opacity value changes when it changes. CSS properties have no value like offsetAlpha. So we define an initial alpha = 30 variable globally to control the change in the current transparency value.
Multi-object animation
If you have multiple elements on a page that move using the motion function. Because the timer returns different values on different elements. So you want to mount the global timer on the current element.
See a BUG
<! DOCTYPEhtml>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>* {padding: 0;
margin: 0;
}
ul{
list-style: none;
}
ul li{
margin: 20px 0;
width: 300px;
height: 150px;
background-color: yellowgreen;
}
</style>
<script type="text/javascript">
window.onload = function() {
var allLis = document.getElementsByTagName('li');
for (var i = 0; i < allLis.length; i++) {
allLis[i].onmouseover = function() {
/** * The first argument is the current object, and the second argument is the target value */
startMove(this.600);
}
allLis[i].onmouseout = function() {
startMove(this.300); }}var speed = 0,
timer = null;
function startMove(ele, target) {
clearInterval(timer);
timer = setInterval(function() {
// 1. Find the step size
speed = (target - ele.offsetWidth) * 0.5;
// 2. Check the speed
speed = target > ele.offsetWidth ? Math.ceil(speed) : Math.floor(speed);
if (ele.offsetWidth == target) {
clearInterval(ele.timer);
} else {
// 3. Get moving
ele.style.width = ele.offsetWidth + speed + 'px'; }},30)}}</script>
</head>
<body>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</body>
</html>
Copy the code
The effect is as follows:
This is clearly not what we want. That’s because we all turn on the timer when we’re levitating fast. The timer cleared by the cleartInterVal() method makes it hard for it to know which timer it cleared. Led to an unexpected effect. To solve this problem, we should mount the timer variable onto the current element
The solution code is as follows:
window.onload = function() {
var allLis = document.getElementsByTagName('li');
for (var i = 0; i < allLis.length; i++) {
allLis[i].onmouseover = function() {
/** * The first argument is the current object, and the second argument is the target value */
startMove(this.600);
}
allLis[i].onmouseout = function() {
startMove(this.300); }}var speed = 0;
function startMove(ele, target) {
clearInterval(ele.timer);
ele.timer = setInterval(function() {
// 1. Find the step size
speed = (target - ele.offsetWidth) * 0.5;
// 2. Check the speed
speed = target > ele.offsetWidth ? Math.ceil(speed) : Math.floor(speed);
if (speed == target) {
clearInterval(ele.timer);
} else {
// 3. Get moving
ele.style.width = ele.offsetWidth + speed + 'px'; }},30)}}Copy the code
Perfect effect
Get the style
We had a lot of problems with multi-object motion last time. For example, if we set the border for the li tag :4px solid #000; You might want to take a look at the effect. (We want it to hover width:600px; Left width:300px). But there are bugs. This is because offsetWidth. So let’s look at that.
Study offsetWidth’s pits
Here’s an example:
<! DOCTYPEhtml>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#box{
width: 200px;
height: 200px;
background-color: red;
border: 1px solid # 000;
}
</style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
window.onload = function (){
var oBox = document.getElementById('box');
move(oBox);
}
function move(obj){
setInterval(function (){
obj.style.width = obj.offsetWidth-1 + 'px';
},30)}</script>
</body>
</html>
Copy the code
I want the width of the box to decrease gradually. However, once you run the above code, you will find something strange and wonder why.
May wish to alert (obj. OffsetWidth); . You’ll see that you get 202. Width = obj.offsetwidth-1 + ‘px’; The resulting width is 201px. It is 1px larger than the width in the original CSS style. Border-left-width + padding-left + width + padding-right + border-right-width; So we cannot get the width of the current box by offsetWidth.
There are two ways to do it
1. Set the width of the in-line style for the current box and use obj.style.width to obtain the width of the current box. But we can’t write all the boxes in the line. Therefore, it is not recommended.
2. Encapsulate your own style function to get attributes
/ * * *@param {Object} Obj which object *@param {Object} Attr what attribute */
function getStyle(obj,attr){
if(obj.currentStyle){
// For Internet Explorer
return obj.currentStyle[attr];
}else{
// For Firefox
return getComputedStyle(obj,null)[attr]; }}Copy the code
The complete code is as follows:
<! DOCTYPEhtml>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#box{
width: 200px;
height: 200px;
background-color: red;
border: 1px solid # 000;
}
</style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
window.onload = function (){
var oBox = document.getElementById('box');
move(oBox);
}
function move(obj){
setInterval(function (){
obj.style.width = parseInt(getStyle(obj,'width')) -1 + 'px';
},30)}/ * * *@param {Object} Obj which object *@param {Object} Attr what attribute */
function getStyle(obj,attr){
if(obj.currentStyle){
// For Internet Explorer
return obj.currentStyle[attr];
}else{
// For Firefox
return getComputedStyle(obj,null)[attr]; }}</script>
</body>
</html>
Copy the code
Multi-object motion complete edition
<! DOCTYPEhtml>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>* {padding: 0;
margin: 0;
}
ul{
list-style: none;
}
ul li{
margin: 20px 0;
width: 300px;
height: 150px;
background-color: yellowgreen;
border: 4px solid # 000;
}
</style>
<script type="text/javascript">
window.onload = function() {
var allLis = document.getElementsByTagName('li');
for (var i = 0; i < allLis.length; i++) {
allLis[i].onmouseover = function() {
/** * The first argument is the current object, and the second argument is the target value */
startMove(this.600);
}
allLis[i].onmouseout = function() {
startMove(this.300); }}var speed = 0;
function startMove(ele, target) {
//1. Turn off and then on the timer
clearInterval(ele.timer);
ele.timer = setInterval(function() {
// 1.1 Get style attributes
var cur = parseInt(getStyle(ele,'width'));
// 1.2. Find the step size
speed = (target - cur) * 0.5;
// 1.3 Check the speed
speed = target > cur ? Math.ceil(speed) : Math.floor(speed);
//1.4 Critical value judgment
if (cur == target) {
clearInterval(ele.timer);
} else {
// get moving
ele.style.width = cur + speed + 'px'; }},30)}}</script>
</head>
<body>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</body>
</html>
Copy the code
More value
What if I want to change both the width of an element and the height of a box? How to do it?
Style [‘width’] = cur + speed + ‘px’; style[‘width’] = cur + speed + ‘px’; In this way, attributes can be put into wrapped functions as parameters.
function startMove(ele,attr,target) {
//1. Turn off and then on the timer
clearInterval(ele.timer);
ele.timer = setInterval(function() {
// 1.1 Get style attributes
var cur = parseInt(getStyle(ele,attr));
// 1.2. Find the step size
speed = (target - cur) * 0.5;
// 1.3 Check the speed
speed = target > cur ? Math.ceil(speed) : Math.floor(speed);
//1.4 Critical value judgment
if (cur == target) {
clearInterval(ele.timer);
} else {
// get moving
ele.style[attr] = cur + speed + 'px'; }},30)}Copy the code
So when the external is called
var allLis = document.getElementsByTagName('li');
allLis[0].onmouseover = function (){
startMove(this.'width'.600);
}
allLis[0].onmouseout = function (){
startMove(this.'width'.300);
}
allLis[1].onmouseover = function (){
startMove(this.'height'.400);
}
allLis[1].onmouseout = function (){
startMove(this.'height'.150);
}
Copy the code
Let me ask you a question: what properties in CSS can’t be implemented with getStyle?
Transparency style processing
In the last class we were left with the question, what attributes can’t getStyle get? In the last code, our motion frame is gradually taking shape, but it’s far from enough, like looking at a bug. Last time code modification
<! DOCTYPEhtml>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>* {padding: 0;
margin: 0;
}
ul{
list-style: none;
}
ul li{
margin: 20px 0;
width: 300px;
height: 150px;
background-color: yellowgreen;
border: 4px solid # 000;
opacity: 0.3;
filter: alpha(opacity: 30);
}
</style>
<script type="text/javascript">
window.onload = function() {
var allLis = document.getElementsByTagName('li');
allLis[0].onmouseover = function (){
startMove(this.'opacity'.100);
}
allLis[0].onmouseout = function (){
startMove(this.'opacity'.30);
}
var speed = 0;
function startMove(ele, attr,target) {
//1. Turn off and then on the timer
clearInterval(ele.timer);
ele.timer = setInterval(function() {
// 1.1 Get style attributes
var cur = parseInt(getStyle(ele,attr));
// 1.2. Find the step size
speed = (target - cur) * 0.5;
// 1.3 Check the speed
speed = target > cur ? Math.ceil(speed) : Math.floor(speed);
//1.4 Critical value judgment
if (cur == target) {
clearInterval(ele.timer);
} else {
// get moving
ele.style[attr] = cur + speed + 'px'; }},30)}/ * * *@param {Object} Obj which object *@param {Object} Attr what attribute */
function getStyle(obj,attr){
if(obj.currentStyle){
// For Internet Explorer
return obj.currentStyle[attr];
}else{
// For Firefox
return getComputedStyle(obj,null)[attr]; }}}</script>
</head>
<body>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</body>
</html>
Copy the code
The effect is as follows:
The value of opacity property does not change at all, for two reasons. Look at the picture
So, given these two reasons, let’s solve these two.
Modify the code as follows:
var speed = 0;
function startMove(ele, attr,target) {
//1. Turn off and then on the timer
clearInterval(ele.timer);
ele.timer = setInterval(function() {
// 1.1 Getting style attributes handles transparency issues
var cur = 0;
if(attr === 'opacity'){
cur = Math.round(parseFloat(getStyle(ele,attr))*100);
}else{
cur = parseInt(getStyle(ele,attr));
}
// 1.2. Find the step size
speed = (target - cur) * 0.5;
// 1.3 Check the speed
speed = target > cur ? Math.ceil(speed) : Math.floor(speed);
//1.4 Critical value judgment
if (cur == target) {
clearInterval(ele.timer);
} else {
if(attr === 'opacity'){
ele.style[attr] = 'alpha(opacity:'+(cur+speed)+') ';
ele.style[attr] = (cur + speed)/100;
}else{
// get moving
ele.style[attr] = cur + speed + 'px'; }}},30)}/ * * *@param {Object} Obj which object *@param {Object} Attr what attribute */
function getStyle(obj,attr){
if(obj.currentStyle){
// For Internet Explorer
return obj.currentStyle[attr];
}else{
// For Firefox
return getComputedStyle(obj,null)[attr]; }}Copy the code
Note: Since transparency involves decimals, such as 0.07*100=> 7.000000000000001, you need to remove the tail with math.round ()
Chain animation
Multiple properties of an object may move simultaneously, or one property may move after another. To achieve this effect, you need to use the callback function.
Results the following
If you want to achieve the above effect. The motion frame we will now encapsulate is stored in a myAnimation.js file.
myAnimation.js
var speed = 0;
/ * * *@param {Object} Ele The current element *@param {Object} Attr An attribute * of the current element@param {Object} * / target goal
function startMove(ele, attr, target,fn) {
//1. Turn off and then on the timer
clearInterval(ele.timer);
ele.timer = setInterval(function() {
// 1.1 Get style attributes
var cur = 0;
if (attr === 'opacity') {
cur = Math.round(parseFloat(getStyle(ele, attr)) * 100);
} else {
cur = parseInt(getStyle(ele, attr));
}
// 1.2. Find the step size
speed = (target - cur) * 0.5;
// 1.3 Check the speed
speed = target > cur ? Math.ceil(speed) : Math.floor(speed);
//1.4 Critical value judgment
if (cur == target) {
clearInterval(ele.timer);
// Where to modify
// Call fn at the end of the call
if(fn){ fn(); }}else {
if (attr === 'opacity') {
ele.style[attr] = 'alpha(opacity:' + (cur + speed) + ') ';
ele.style[attr] = (cur + speed) / 100;
} else {
// get moving
ele.style[attr] = cur + speed + 'px'; }}},30)}/ * * *@param {Object} Obj which object *@param {Object} Attr what attribute */
function getStyle(obj, attr) {
if (obj.currentStyle) {
// For Internet Explorer
return obj.currentStyle[attr];
} else {
// For Firefox
return getComputedStyle(obj, null)[attr]; }}Copy the code
External references.
<! --1. Introduce external modules first -->
<script src="js/myAnimation.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
window.onload = function() {
//2. Get the element
var oBox = document.getElementById('box');
//3
oBox.onmouseover = function() {
// Be careful with the reference to this in the callback function. The reference to this in the callback refers to the window object
var that = this;
/ / 3. The movement
startMove(this.'width'.500.function(){
startMove(that,'height'.400);
});
}
oBox.onmouseout = function() {
var that = this;
startMove(this.'height'.200.function(){
startMove(that,'width'.200); }); }}</script>
Copy the code
At the same time movement
If the previous motion frame, we wanted the element to be able to change both width and transparency. This is where we use JSON. We’ll talk about JSON in more detail later in the class, but let’s use it briefly for now
var json = {
"name":"mjj"."age":29
}
for(var attr in json){
alert(attr); // Get the attribute name
alert(json[attr]);// Get the attribute value
}
Copy the code
With the simple JSON usage above, we’ll modify myanimation.js.
var speed = 0;
/ * * *@param {Object} Ele The current element *@param {Object} Json Current element numeric key value versus JSON data *@param {Object} Fn Current callback function */
function startMove(ele, json,fn) {
//1. Turn off and then on the timer
clearInterval(ele.timer);
ele.timer = setInterval(function() {
for(var attr in json){
// 1.1 Get style attributes
var cur = 0;
if (attr === 'opacity') {
cur = Math.round(parseFloat(getStyle(ele, attr)) * 100);
} else {
cur = parseInt(getStyle(ele, attr));
}
// 1.2. Find the step size
speed = (json[attr] - cur) * 0.5;
// 1.3 Check the speed
speed = json[attr] > cur ? Math.ceil(speed) : Math.floor(speed);
//1.4 Critical value judgment
if (cur == json[attr]) {
clearInterval(ele.timer);
// Call fn at the end of the call
if(fn){ fn(); }}else {
if (attr === 'opacity') {
ele.style[attr] = 'alpha(opacity:' + (cur + speed) + ') ';
ele.style[attr] = (cur + speed) / 100;
} else {
// get moving
ele.style[attr] = cur + speed + 'px'; }}}},30)}/ * * *@param {Object} Obj which object *@param {Object} Attr what attribute */
function getStyle(obj, attr) {
if (obj.currentStyle) {
// For Internet Explorer
return obj.currentStyle[attr];
} else {
// For Firefox
return getComputedStyle(obj, null)[attr]; }}Copy the code
<script src="js/myAnimation2.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
window.onload = function() {
var oBox = document.getElementById('box');
oBox.onmouseover = function() {
startMove(oBox,{"width":400."height":400.'opacity': 100})
}
oBox.onmouseout = function() {
startMove(oBox,{"width":200."height":200.'opacity': 30}}})</script>
Copy the code
The effect is as follows:
Through the above modification, we achieved the desired effect. Really ?????? See a bug. Modify the code
<script src="js/myAnimation2.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
window.onload = function() {
var oBox = document.getElementById('box');
oBox.onmouseover = function() {
startMove(oBox,{"width":201."height":400.'opacity': 100})
}
oBox.onmouseout = function() {
startMove(oBox,{"width":200."height":200.'opacity': 30}}})</script>
Copy the code
The BUG effect is as follows:
It seems that the wrapped myAnimation.js motion framework has a problem. The analysis causes are shown in the figure:
That is, the timer is turned off when all the attributes in the JSON have reached their destination value. In other words, the timer cannot be turned off until the end value of the property in the JSON is reached.
Modify the code as follows:
var speed = 0;
/ * * *@param {Object} Ele The current element *@param {Object} Json Current element numeric key value versus JSON data *@param {Object} Fn Current callback function */
function startMove(ele, json, fn) {
//1. Turn off and then on the timer
clearInterval(ele.timer);
ele.timer = setInterval(function() {
// Make a benchmark, if true, to prove that all attributes have reached their destination value
var flag = true;
for (var attr in json) {
// console.log(attr,json[attr]);
// 1.1 Get style attributes
var cur = 0;
if (attr === 'opacity') {
cur = Math.round(parseFloat(getStyle(ele, attr)) * 100);
} else {
cur = parseInt(getStyle(ele, attr));
}
// 1.2. Find the step size
speed = (json[attr] - cur) / 20;
// 1.3 Check the speed
speed = json[attr] > cur ? Math.ceil(speed) : Math.floor(speed);
// 1.4 If all attributes do not reach the end value. Proceed with the following code
if(cur ! == json[attr]){ flag =false;
}
//1.5 Handle property named opacity
if (attr === 'opacity') {
/ / 1.5.1 compatible with IE
ele.style[attr] = 'alpha(opacity:' + (cur + speed) + ') ';
//1.5.2 W3C Browser
ele.style[attr] = (cur + speed) / 100;
} else {
// 1.6 Get moving
ele.style[attr] = cur + speed + 'px'; }}// 1.6 If flag is true, it indicates that all attributes have reached the end point. At this point, the timer is cleared and the callback function is executed
if (flag) {
clearInterval(ele.timer);
if(fn) { fn(); }}},30)}/ * * *@param {Object} Obj which object *@param {Object} Attr what attribute */
function getStyle(obj, attr) {
if (obj.currentStyle) {
// For Internet Explorer
return obj.currentStyle[attr];
} else {
// For Firefox
return getComputedStyle(obj, null)[attr]; }}Copy the code
So far our motion frame is almost complete and can be applied to many effects on a web page. For example: infinite rotation graphics effects, linkage effects, navigation animation effects