最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

通用的匀速运动框架如何打造

来源:懂视网 责编:小OO 时间:2020-11-27 20:05:54
文档

通用的匀速运动框架如何打造

本文,是接着上 基于匀速运动的实例讲解(侧边栏,淡入淡出) 继续的,在这篇文章的最后,我们做了2个小实例:侧边栏与改变透明度的淡入淡出效果,本文我们把上文的animate函数,继续改造,让他变得更加的通用和强大。1,支持多个物体的运动。2,同时运动;3,顺序运动;这三种运动方式也是jquery中animate函数支持的。一、animate函数中怎么区分变化不同的样式。上文中,侧边栏效果 用的animate函数 改变的是left值。
推荐度:
导读本文,是接着上 基于匀速运动的实例讲解(侧边栏,淡入淡出) 继续的,在这篇文章的最后,我们做了2个小实例:侧边栏与改变透明度的淡入淡出效果,本文我们把上文的animate函数,继续改造,让他变得更加的通用和强大。1,支持多个物体的运动。2,同时运动;3,顺序运动;这三种运动方式也是jquery中animate函数支持的。一、animate函数中怎么区分变化不同的样式。上文中,侧边栏效果 用的animate函数 改变的是left值。
本文主要为大家带来一篇打造通用的匀速运动框架(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。

本文,是接着上 基于匀速运动的实例讲解(侧边栏,淡入淡出) 继续的,在这篇文章的最后,我们做了2个小实例:侧边栏与改变透明度的淡入淡出效果,本文我们把上文的animate函数,继续改造,让他变得更加的通用和强大:

1,支持多个物体的运动

2,同时运动

3,顺序运动

这三种运动方式也是jquery中animate函数支持的

一、animate函数中怎么区分变化不同的样式?

上文中,侧边栏效果 用的animate函数 改变的是left值

function animate(obj, target, speed) {
 clearInterval(timer);
 timer = setInterval(function () {
 if (obj.offsetLeft == target) {
 clearInterval(timer);
 } else {
 obj.style.left = obj.offsetLeft + speed + 'px';
 }
 }, 30);
}

淡入淡出效果 用的animate函数 改变的是透明度

function animate(obj, target, speed) {
 clearInterval(timer);
 var cur = 0;
 timer = setInterval(function () {
 cur = css( obj, 'opacity') * 100;
 if( cur == target ){
 clearInterval( timer );
 }else {
 cur += speed;
 obj.style.opacity = cur / 100;
 obj.style.filter = "alpha(opacity:" + cur + ")";
 }
 }, 30);
 }

而我们封装的函数,要变成通用的,首先面临的问题就是 这个函数要同时支持left值和透明度的变化,更通用的做法应该是要支持所有的样式变化,比如轮播功能,他有左右滑动,也有上下滑动。

我们可以在获取样式和改变样式的时候,做一下判断就可以了,判断分2类就能达到目的,因为其他样式( margin, left, top, right, font-size等等 )都是px,而透明度没有px单位

function animate(obj, attr, target, speed) {
 clearInterval(timer);
 var cur = 0;
 timer = setInterval(function () {
 if (attr == 'opacity') {
 cur = css(obj, 'opacity') * 100;
 } else {
 cur = parseInt(css(obj, attr));
 }

 if (cur == target) {
 clearInterval(timer);
 } else {
 if (attr == 'opacity') {
 obj.style.opacity = ( cur + speed ) / 100;
 obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";
 } else {
 obj.style[attr] = cur + speed + "px";
 }
 }
 }, 30);
}

合并之后的animate相比之前多了一个参数attr, 这个参数就是变化的样式,obj: 变化的对象, target: 样式需要变化到的目标值. speed: 样式每次变化的大小

如:

oImg.onmouseover = function () {
  animate(this, 'opacity', 100, 10);
}

oImg是获取到的图片对象. 这里各参数意思如下:

this:当前图片对象

opacity: 变化的样式是透明度

100: 鼠标移到图片上时,透明度变成100

10: 透明度每次在原来的基础上加10

<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>合并的运动 - by ghostwu</title>
 <style>
 img {
 border: none;
 opacity: 0.3;
 filter: alpha(opacity:30);
 position: absolute;
 left: 200px;
 }

 #box {
 width: 150px;
 height: 300px;
 background: red;
 position: absolute;
 left: -150px;
 top: 50px;
 }

 #box p {
 width: 28px;
 height: 100px;
 position: absolute;
 right: -28px;
 top: 100px;
 background: green;
 }
 </style>
 <script>
 window.onload = function () {
 var oImg = document.getElementById("img"),
 oBox = document.getElementById("box"),
 timer = null;

 oImg.onmouseover = function () {
 animate(this, 'opacity', 100, 10);
 }
 oImg.onmouseout = function () {
 animate(this, 'opacity', 30, -10);
 }

 oBox.onmouseover = function () {
 animate(this, 'left', 0, 10);
 }

 oBox.onmouseout = function () {
 animate(this, 'left', -150, -10);
 }

 function animate(obj, attr, target, speed) {
 clearInterval(timer);
 var cur = 0;
 timer = setInterval(function () {
 if (attr == 'opacity') {
 cur = css(obj, 'opacity') * 100;
 } else {
 cur = parseInt(css(obj, attr));
 }

 if (cur == target) {
 clearInterval(timer);
 } else {
 if (attr == 'opacity') {
 obj.style.opacity = ( cur + speed ) / 100;
 obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";
 } else {
 obj.style[attr] = cur + speed + "px";
 }
 }
 }, 30);
 }

 function css(obj, attr) {
 if (obj.currentStyle) {
 return obj.currentStyle[attr];
 } else {
 return getComputedStyle(obj, false)[attr];
 }
 }
 }
 </script>
</head>
<body>
<p id="box">
 <p>分享到</p>
</p>
<img src="./img/h4.jpg" alt="" id="img"/>
</body>
</html>

上述就是完整的代码实例。

当你分别测试这两个功能的时候:

移动到图片上然后移出来

移动到分享到,然后移出来

这样是没有问题的

如果你这样测试:

移动到 分享到,然后迅速又移动到图片上, 这个时候你会发现 分享到 停下来了,这就不符合逻辑了! 按道理来说,鼠标移动到图片上,相当于触发了 “分享到” 的mouseout( 鼠标移出事件 ),那么 "分享到" 这个时候要隐藏,并不是停止。 为什么会这样呢?因为这两个运动共享了一个定时器,当鼠标移动到图片上,开启定时器的时候,把“分享到”的定时器给停了。那么再做多物体运动的时候,我们就要把定时器拆分,每个对象都要有一个定时器,怎么做呢? 非常简单,不要定义一个简单的timer变量,我们只要把timer加在obj对象上,那么每个对象都有一个timer属性,就达到定时器的分离效果了

修改之后的完整代码如下,请自行展开:

<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <style>
 img {
 border: none;
 opacity: 0.3;
 filter: alpha(opacity:30);
 position: absolute;
 left: 200px;
 }

 #box {
 width: 150px;
 height: 300px;
 background: red;
 position: absolute;
 left: -150px;
 top: 50px;
 }

 #box p {
 width: 28px;
 height: 100px;
 position: absolute;
 right: -28px;
 top: 100px;
 background: green;
 }
 </style>
 <script>
 window.onload = function () {
 var oImg = document.getElementById("img"),
 oBox = document.getElementById("box");

 oImg.onmouseover = function () {
 animate(this, 'opacity', 100, 10);
 }
 oImg.onmouseout = function () {
 animate(this, 'opacity', 30, -10);
 }

 oBox.onmouseover = function () {
 animate(this, 'left', 0, 10);
 }

 oBox.onmouseout = function () {
 animate(this, 'left', -150, -10);
 }

 function animate(obj, attr, target, speed) {
 clearInterval(obj.timer);
 var cur = 0;
 obj.timer = setInterval(function () {
 if (attr == 'opacity') {
 cur = css(obj, 'opacity') * 100;
 } else {
 cur = parseInt(css(obj, attr));
 }

 if (cur == target) {
 clearInterval(obj.timer);
 } else {
 if (attr == 'opacity') {
 obj.style.opacity = ( cur + speed ) / 100;
 obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";
 } else {
 obj.style[attr] = cur + speed + "px";
 }
 }
 }, 30);
 }

 function css(obj, attr) {
 if (obj.currentStyle) {
 return obj.currentStyle[attr];
 } else {
 return getComputedStyle(obj, false)[attr];
 }
 }
 }
 </script>
</head>
<body>
<p id="box">
 <p>分享到</p>
</p>
<img src="./img/h4.jpg" alt="" id="img"/>
</body>
</html>

至此,我们就完成了多物体运动与不同样式的修改

二、让animate函数支持多个样式同时改变

比如:

oBox.onmouseover = function(){
  animate( this, { "width" : 500, "height" : 400 }, 10 );
}

oBox是一个p元素,animate各参数的意思:

this: 当前p元素

{width : 500, "height" : 400 } : 把宽度变成500, 高度变成400,这两个样式要在同一时间完成,

10: 样式每次在原来的基础上变化10(如width初始值200--> 210, 220, 230.....)

完整的同时运动变化 代码:

<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <style>
 p {
 width: 200px;
 height: 200px;
 background: red;
 }
 </style>
 <script>
 window.onload = function () {
 var oBox = document.getElementById("box");
 oBox.onmouseover = function(){
// animate( this, { "width" : 500, "height" : 500 }, 10 );
 animate( this, { "width" : 500, "height" : 400 }, 10 );
 }

 function animate(obj, attr, speed) {
 clearInterval(obj.timer);
 var cur = 0;
 obj.timer = setInterval(function () {
 for ( var key in attr ) {
 if (key == 'opacity') {
 cur = css(obj, 'opacity') * 100;
 } else {
 cur = parseInt(css(obj, key));
 }
 var target = attr[key];
 if (cur == target) {
 clearInterval(obj.timer);
 } else {
 if (key == 'opacity') {
 obj.style.opacity = ( cur + speed ) / 100;
 obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";
 } else {
 obj.style[key] = cur + speed + "px";
 }
 }
 }
 }, 30);
 }

 function css(obj, attr) {
 if (obj.currentStyle) {
 return obj.currentStyle[attr];
 } else {
 return getComputedStyle(obj, false)[attr];
 }
 }
 }
 </script>
</head>
<body>
 <p id="box"></p>
</body>
</html>

请自行展开这段代码,这段代码能够同时运动,但是有一个问题:

p的初始宽度与高度( width : 200, height : 200)

变化步长一样( 10 )

变化时间一样( 每30毫秒变化一次 )

目标( width: 500, height : 400 )

你能想到什么问题吗?( 两个人在同一起跑线上,速度一样, 时间一样,但是要同时到达不同的目标,一个500, 一个400 )

答案是很明显的,肯定是目标近的( height : 400 )那个先到达,然后把对象上的定时器关了,另一个目标更远的( width: 500 )肯定到达不了

你可以在这句代码下面,输出当前的值和目标值:

var target = attr[key];
console.log( key, cur, target );

输出来的结果是:

从上图可以看出,height已经达到了400px,但是width停在了410px,为什么不是400px ? 因为width = 400的时候, 就是( cur == 500 ) 相当于( 400 == 500 ) 不成立,所以执行了else语句,width = cur + 10 = 400 + 10 = 410,然后height到达400px停止了定时器,所以width停在了410px.

那么我们怎么解决这个问题呢?

其实也好办,就是height = 400的时候 不要把定时器关了,应该等width = 500的时候再关闭定时器,不就在同一时间,完成了同时到达目标的效果吗?

修改后的代码如下:

<!doctype html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <style>
 p {
 width: 200px;
 height: 200px;
 background: red;
 }
 </style>
 <script>
 window.onload = function () {
 var oBox = document.getElementById("box");
 oBox.onmouseover = function(){
 animate( this, { "width" : 500, "height" : 400 }, 10 );
 }

 function animate(obj, attr, speed) {
 clearInterval(obj.timer);
 var cur = 0;
 obj.timer = setInterval(function () {
 var bFlag = true;
 for ( var key in attr ) {
 if (key == 'opacity') {
 cur = css(obj, 'opacity') * 100;
 } else {
 cur = parseInt(css(obj, key));
 }
 var target = attr[key];
 if (cur != target) {
 bFlag = false;
 if (key == 'opacity') {
 obj.style.opacity = ( cur + speed ) / 100;
 obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";
 } else {
 obj.style[key] = cur + speed + "px";
 }
 }
 }
 if ( bFlag ) {
 clearInterval( obj.timer );
 }
 }, 30);
 }

 function css(obj, attr) {
 if (obj.currentStyle) {
 return obj.currentStyle[attr];
 } else {
 return getComputedStyle(obj, false)[attr];
 }
 }
 }
 </script>
</head>
<body>
 <p id="box"></p>
</body>
</html>

声明一个变量,每次变化完一次( width, height )样式 把bFlag = true, 只要在for循环中有一个没有到达目标,bFlag的值都是false,这样就不会关闭定时器。当两个都到达目标,才关闭定时器.

三、顺序运动

如样式变化,按顺序来,不是同时变化, 如:

oBox.onmouseover = function(){
//回调函数: 把函数当做参数传递给另一个函数
  animate( this, { 'width' : 500 }, 10, function(){
    animate( this, { 'height' : 500 }, 10 );
  } );
}

当把width变成500px的时候,如果传递了回调函数, 再接着执行回调函数里面的运动

修改后的完整代码:

<!DOCTYPE html>
<html>
<head lang="en">
 <meta charset="UTF-8">
 <title>通用的匀速运动框架 - by ghostwu</title>
 <style>
 p {
 width: 200px;
 height: 200px;
 background: red;
 }
 </style>
 <script>
 window.onload = function () {
 var oBox = document.getElementById("box");
 oBox.onmouseover = function(){
 //回调函数: 把函数当做参数传递给另一个函数
 animate( this, { 'width' : 500 }, 10, function(){
 animate( this, { 'height' : 500 }, 10 );
 } );
 }

 function animate(obj, attr, speed, fn ) {

 clearInterval(obj.timer);
 var cur = 0;
 obj.timer = setInterval(function () {
 var bFlag = true;
 for (var key in attr) {
 if (key == 'opacity') {
 cur = css(obj, 'opacity') * 100;
 } else {
 cur = parseInt(css(obj, key));
 }
 var target = attr[key];
 if (cur != target) {
 bFlag = false;
 if (key == 'opacity') {
 obj.style.opacity = ( cur + speed ) / 100;
 obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";
 } else {
 obj.style[key] = cur + speed + "px";
 }
 }
 }

 if (bFlag) {
 clearInterval(obj.timer);
 fn && fn.call( obj );
 }
 }, 30);
 }

 function css(obj, attr) {
 if (obj.currentStyle) {
 return obj.currentStyle[attr];
 } else {
 return getComputedStyle(obj, false)[attr];
 }
 }
 }
 </script>
</head>
<body>
<p id="box"></p>
</body>
</html>

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

通用的匀速运动框架如何打造

本文,是接着上 基于匀速运动的实例讲解(侧边栏,淡入淡出) 继续的,在这篇文章的最后,我们做了2个小实例:侧边栏与改变透明度的淡入淡出效果,本文我们把上文的animate函数,继续改造,让他变得更加的通用和强大。1,支持多个物体的运动。2,同时运动;3,顺序运动;这三种运动方式也是jquery中animate函数支持的。一、animate函数中怎么区分变化不同的样式。上文中,侧边栏效果 用的animate函数 改变的是left值。
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top