最近学习了物体的运动框架,觉得有必要做下总结!

1. 匀速运动

首先准备一个div,css样式如下:

          #div1 {width: 200px;height: 200px;background: red;position: absolute;left: 0;top: 0;}

  接下来,我们让这个div动起来

function startMove(obj, iTarget) {clearInterval(obj.timer);  //防止重复开启定时器obj.timer = setInterval(function() {var speed = obj.offsetLeft < iTarget ? 10 : -10;  //判断速度的正负if (obj.offsetLeft == iTarget) {clearInterval(obj.timer);  //达到目标,关闭定时器} else {obj.style.left = obj.offsetLeft + speed + 'px';}}, 30);}

  div每30毫秒向右运动10px,当div.style.left等于iTarget的时候,停下来,这段代码看似没有问题。其实当速度设置 7 的时候,问题就出来了。当div.style.left增加到 399的时候,再增加一个7 就变成 406了,div发现多了6, 就会减7 ,发现又少了……反反复复,div.style.left就是到不了目标位置,div也就停不下来了。

  修改代码,注意红色代码:

            function startMove2(obj, iTarget) {clearInterval(obj.timer);obj.timer = setInterval(function() {var speed = obj.offsetLeft < iTarget ? 7 : -7;if (Math.abs(obj.offsetLeft - iTarget) <= speed) {clearInterval(obj.timer); obj.style.left = iTarget + 'px';} else {obj.style.left = obj.offsetLeft + speed + 'px';}}, 30);}

这样,不管速度设置是多少,都能停下来。

2. 变速运动

变速运动关键在于速度不是一个定值,它一般随着距离的减小而减小,换句话说,距离目标大的时候速度快,距离目标小的时候速度慢。

如何做到这一点呢? 将目标值与当前值相减的差值 除以 一个数(这个数的大小由你决定),这样速度就在不断变化。具体看代码:

 1             function startMove3(obj, iTarget) {
 2                 clearInterval(timer);
 3                 timer = setInterval(function() {
 4                     var speed = (iTarget - obj.offsetHeight) / 10;
 5
 6                     if (obj.offsetHeight == iTarget) {
 7                         clearInterval(timer);
 8                     } else {
 9                         obj.style.height = obj.offsetHeight + speed + 'px';
10                     }
11                 }, 30);
12             }

同样也是存在问题的。最后速度会变成零点几,一个小数,但css能分辨的最小单位是1px,零点几的px都默认是0,因此物体会在目标值前面一小段距离停止不动,尽管定时器还没满足关闭的条件,但是速度已经为0,每次都是加零,所以停止不动了。

改进代码:

            function startMove3(obj, iTarget) {clearInterval(timer);timer = setInterval(function() {var speed = (iTarget - obj.offsetHeight) / 10;speed = obj.offsetHeight < iTarget ? Math.ceil(speed) : Math.floor(speed);if (obj.offsetHeight == iTarget) {clearInterval(timer);} else {obj.style.height = obj.offsetHeight + speed + 'px';}}, 30);}

3. 函数的改进

  以上函数都有一个确定,将改变的属性设死了,要么只能变化高度或宽度。我们可以再加入一个 attribute 参数 ,使得函数更加灵活。

  改进代码:

            function startMove(obj, attribute, iTarget) {clearInterval(obj.timer);obj.timer = setInterval(function() {var cur = parseInt(getStyle(obj, attribute));var speed = (iTarget - cur) / 6;speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);if (cur == iTarget) {clearInterval(obj.timer);} else {obj.style[attribute] = cur + speed + 'px';}}, 30);}//获取元素的CSS属性function getStyle(obj, name) {if (obj.currentStyle) {return obj.currentStyle[name];} else {return getComputedStyle(obj, false)[name];}}

  其中,getStyle(obj,name)是一个获取css属性的函数。

  这个运动函数目前只能针对属性值含有px的,因此我们还需要多一条判断满足透明度改变的需求。

  改进2:

            function startMove(obj, attribute, iTarget) {clearInterval(obj.timer);obj.timer = setInterval(function() {var cur = attribute == 'opacity' ? Math.round(parseFloat(getStyle(obj, attribute) * 100)) : parseInt(getStyle(obj, attribute));var speed = (iTarget - cur) / 6;speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);if (cur == iTarget) {clearInterval(obj.timer);} else {if (attribute == 'opacity') {obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";  //针对IEobj.style.opacity = (cur + speed) / 100;  //针对FireFox Chrome} else {obj.style[attribute] = cur + speed + 'px';}}}, 30);}

  代码中 Math.round(parseFloat(getStyle(obj, attribute) * 100))  对 opacity 数值的处理 , 由于不同浏览器对小数取舍不一样,使用Math.round() 进行四舍五入 , 这样有的浏览器不会出现透明度到达目标值后闪了。

4. 链式运动

            function startMove(obj, attribute, iTarget ,fnEnd) {clearInterval(obj.timer);obj.timer = setInterval(function() {var cur = attribute == 'opacity' ? Math.round(parseFloat(getStyle(obj, attribute) * 100)) : parseInt(getStyle(obj, attribute));var speed = (iTarget - cur) / 6;speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);if (cur == iTarget) {clearInterval(obj.timer);if(fnEnd){fnEnd();}} else {if (attribute == 'opacity') {obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";obj.style.opacity = (cur + speed) / 100;} else {obj.style[attribute] = cur + speed + 'px';}}}, 30);}

5. 多值多属性同时运动

  引入一个json {width : target1,height:target2,opacity:target3}.

function startMove(obj, json, fnEnd) {clearInterval(obj.timer);obj.timer = setInterval(function() {for (var attr in json) {var cur = attr == 'opacity' ? Math.round(parseFloat(getStyle(obj, attr) * 100)) : parseInt(getStyle(obj, attr));var speed = (json[attr] - cur) / 6;speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);if (cur == json[attr]) {clearInterval(obj.timer);if (fnEnd) {fnEnd();}} else {if (attr == 'opacity') {obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";obj.style.opacity = (cur + speed) / 100;} else {obj.style[attr] = cur + speed + 'px';}}}}, 30);}

  如果多个属性目标值不一致,定时器启动的时候,目标值小的属性会先满足了关闭定时器的条件,而目标值大的属性还没有到达目标,因此会产生偏差。

  改进代码(最终完美版运动代码):

function startMove(obj, json, fnEnd) {clearInterval(obj.timer);obj.timer = setInterval(function() {var bStop = true;for (var attr in json) {var cur = attr == 'opacity' ? Math.round(parseFloat(getStyle(obj, attr) * 100)) : parseInt(getStyle(obj, attr));var speed = (json[attr] - cur) / 6;speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);if (cur != json[attr]) {bStop = false;}if (attr == 'opacity') {obj.style.filter = "alpha(opacity:" + (cur + speed) + ")";obj.style.opacity = (cur + speed) / 100;} else {obj.style[attr] = cur + speed + 'px';}}if(bStop){clearInterval(obj.timer);if(fnEnd){fnEnd();}}}, 30);}

转载于:https://www.cnblogs.com/dontStopByTime/p/5509183.html

JavaScript 物体的运动相关推荐

  1. js改变宽高字体大小透明度多物体模块运动

    改变宽高字体大小透明度 #div1 { width: 100px; height: 100px; background: red; margin: 10px; filter:alpha(opactiy ...

  2. 【Unity入门】10.物体的运动

    [Unity入门]物体的运动     大家好,我是Lampard~~     欢迎来到Unity入门系列博客,所学知识来自B站阿发老师~感谢 (一)用脚本驱动物体移动 (1)制作一台运动的小车     ...

  3. Javascript 链式运动框架——逐行分析代码,让你轻松了解运动的原理

    所谓链式运动,就是一环扣一环.我们的很多运动实际上来说指的就是分阶段的,第一个阶段动完,下个阶段开始动. 这个链式运动框架就是用来处理这些问题的. 我们先来看下之前的运动框架,以下是Javascrip ...

  4. pygame里面物体闪烁运动_教师资格【试讲示范】高中物理试讲答辩——《自由落体运动》试讲稿答辩...

    试讲备课纸 教学过程 各位考官: 大家好,我是高中物理组的***号考生,我试讲的题目是<自由落体运动>,下面开始我的试讲. 一.导入新课 同学们,老师手里现在拿着一个小笔记本和一张纸,现在 ...

  5. pygame里面物体闪烁运动_利用自闪烁发光二极管探究小车在倾斜轨道上的运动规律...

    2020年11月23日,周一,24小时安全值班.利用当班中午的时间,微主在创客空间测试了自闪烁发光二极管在匀加速运动中的效果,结果还比较满意. 将小车放置在倾斜的轨道上,将自闪烁发光二极管和纽扣电池构 ...

  6. 点滴积累【JS】---JS小功能(JS实现多物体缓冲运动)

    效果: 思路: 利用setInterval计时器进行运动,offsetWidth实现宽度的变动,在用onmouseover将终点和所选中的DIV放入参数再进行缓冲运动. 代码: 1 <head ...

  7. javascript——小方块运动

    关于小方块的运动,包含加速,停止 <!DOCTYPE html> <html lang="en"> <head><meta charset ...

  8. Canvas实现物体基本运动

      动画中最常见的就是物体运动.物体的位置随时间变化而变化,变化的规律不同,运行的形式也不同.本文学习参考文献1中的几种运动形式,并实践其中的案例. 匀速运动   匀速运动是人们很熟悉的运动方式,初. ...

  9. pygame里面物体闪烁运动_Pygame-游戏中的运动

    本来,在上一次pygame的教程中,我只是顺手拿了微信"打飞机"里的图来演示用鼠标控制图片位置的操作.后来觉得,这个游戏还算比较适合用来做例子,也有朋友反馈说想做这个游戏,那不如就 ...

  10. 自由运动物体的运动代码

    //I/O口以及其他信号啥的 ARCHITECTURE ONE OF SPORTS IS SIGNAL HCNT:STD_LOGIC_VECTOR(0 to 9); SIGNAL VCNT:STD_L ...

最新文章

  1. 968. 监控二叉树(递归+贪心)
  2. ASP——判断数据库NULL值
  3. 支持python开发的环境有哪些变化_Python开发实践:打造完美的项目工程环境
  4. ES使用脚本进行局部更新的排错记录
  5. mysql 可重复读 更新覆盖_Mysql事务隔离级别之可重复读
  6. python n个list如何组成矩阵_有序矩阵中第K小的元素amp;x的平方根(二分法篇)
  7. SpringMVC框架----SpringMVC 概述
  8. 淘宝天猫店铺,竞争对手卖同款产品,价格比我低,标题一模一样,如何应对?
  9. seleuium 禁止检测_如何突破网站对selenium的屏蔽
  10. python如何得出数组里最大_如何理解Python里的字典dict?
  11. word中设置论文中英文参考文献对齐方法
  12. Atitit React的相关概念东东 attilax总结 v3
  13. Apache commons-text和Configuration 命令执行CVE-2022-42889/CVE-2022-33980分析
  14. python破解qq空间访问权限_怎么利用爬虫爬取QQ空间中设置了权限的无法正常访问的内容?...
  15. 给mBlock添加扩展模块
  16. 基于STM32完成FATFS文件系统移植与运用--这是完全免费开源的FAT文件系统
  17. java研发手机归属地批量查询
  18. windows10安装NVIDIA显卡驱动+cuda10.0教程
  19. 零基础H5小游戏傻瓜教程_教您如何制作微信小游戏
  20. Mac 如何彻底删除/卸载程序

热门文章

  1. 「三分钟系列05」3分钟看懂并发与并行
  2. 神奇的反爬措施--大众点评
  3. php解密 hr+c_PHP每15分钟自动更新网站地图(减少服务器消耗)
  4. 手机 com.android.backupconfirm可以删除吗,手机上什么文件可以删除?答案都在这里了...
  5. Android Framework 全面分析 SystemServer
  6. 1009 说反话 (20 分)—PAT (Basic Level) Practice (中文)
  7. Android BroadcastReceiver(一)
  8. MFC编码注意(2)
  9. 渣渣菜鸡的 ElasticSearch 源码解析 —— 环境搭建
  10. 利用百度搜索结果爬取邮箱