JavaScript运动框架 解决速度正负取整问题(一)


Posted in Javascript onMay 17, 2017

这里说的运动是指缓冲运动,缓冲运动会使物体逐渐‘着陆',而不是‘硬着陆',到达目标位置的过程中速度越来越慢,看起来很舒服。

缓冲的特点:

  • 速度随着距离的缩短而降低
  • 速度 = (目标值 - 当前值) / 缩放系数;
  • 速度一定要是整数

比如,一个div从最左边运动到left等于400的位置停下,可以如下实现:

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>运动框架(一)</title>
 <style type="text/css">
  * {
   padding: 0;
   margin: 0;
  }
  #div1 {
   width: 100px;
   height: 100px;
   background: orange;
   position: absolute;
  }
  #div2 {
   width: 1px;
   height: 300px;
   background: black;
   position: absolute;
   left: 400px;
  }
  #btn1 {
   width: 60px;
   height: 40px;
   background: #fff;
   position: absolute;
   left: 10px;
   top: 150px;
  }
 </style>
</head>
<body>
 <div id="div1"></div>
 <div id="div2"></div>
 <input id="btn1" type="button" value="start" onclick="startMove()" />
 <script type="text/javascript">
  var oDiv = document.getElementById('div1');
  var oBtn = document.getElementById('btn1');
  var timer = null;
  function startMove() {
   /* 每次启动定时器应该把上次的定时器清理掉,
    因为有的人会多次点击按钮,多次启动定时器,速度会叠加越来越快!
   */
   clearInterval(timer);
   timer = setInterval(function() {
    //每次速度都随着距离的缩短而变慢
    var speed = (400 - oDiv.offsetLeft) / 10;
    if (oDiv.offsetLeft == 400) {
     clearInterval(timer); 
    } else {
     oDiv.style.left = oDiv.offsetLeft + speed + 'px';
     document.title = oDiv.offsetLeft + ' , ' + speed;
    }
   }, 30);
  }
 </script>
</body>
</html>

JavaScript运动框架 解决速度正负取整问题(一)

JavaScript运动框架 解决速度正负取整问题(一)

你会发现,启动按钮之后,div并没有准确到达400的位置,再看看title上打印的实际目标和速度,我们发现最终落脚点是396,速度为0.4,我们知道:1px是最小单位,没有小数的概念,所以0.4px是没有的概念,会被计算机认为是0px,仔细分析,当div运行到396px的时候,还剩下4px,速度为4/10 = 0.4,下一个单位时间(30ms)向前运行0.4px,实际上是0,所以永远的停下来了,而且永远不会执行清除定时器这一步!
怎么解决,Math中有个方法叫向上取整,也就是让速度取整,向上取整,努力帮助div跨过这一步

Math.ceil(3.2) ==> 4
Math.ceil(-9.7) ==> -9
Math.floor(5.98) ==> 5
function startMove() {
 clearInterval(timer);
 timer = setInterval(function() {
  var speed = (400 - oDiv.offsetLeft) / 10;
  speed = Math.ceil(speed);//划重点,划重点
  if (oDiv.offsetLeft == 400) {
   clearInterval(timer);
  } else {
   oDiv.style.left = oDiv.offsetLeft + speed + 'px';
   document.title = oDiv.offsetLeft + ' , ' + speed;
  }
 }, 30);
}

JavaScript运动框架 解决速度正负取整问题(一)

当然了,div除了可以正向运动,也可以负向运动,比如,从800运动到400.
如果不取整的话,依旧不能准确到达400。

#div1 {
 width: 100px;
 height: 100px;
 background: orange;
 position: absolute;
 left: 800px;/*0 --> 800*/
}

JavaScript运动框架 解决速度正负取整问题(一)

function startMove() {
 clearInterval(timer);
 timer = setInterval(function() {
  var speed = (400 - oDiv.offsetLeft) / 10;
  console.log('speed = ' + speed);
  speed = Math.floor(speed);//划重点,划重点,划重点
  if (oDiv.offsetLeft == 400) {
   clearInterval(timer);
  } else {
   oDiv.style.left = oDiv.offsetLeft + speed + 'px';
   document.title = oDiv.offsetLeft + ' , ' + speed;
  }
 }, 30);
}

JavaScript运动框架 解决速度正负取整问题(一)

总结:

正向运动(速度 > 0), Math.ceil(speed);
反向运动(速度 < 0), Math.floor(speed);

var speed = (iTarget - cur) / 系数;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
function startMove(iTarget) {
 setInterval(function() {
  var speed = (iTarget- oDiv.offsetLeft) / 10;
  speed = speed > 0 ? Math.ceil(speed) : Match.floor(speed);
  oDiv.style.left = oDiv.offsetLeft + speed + 'px';
 }, 30);
}

速度取整,是为了最后时刻速度(绝对值)变大,跨过那一槛,不然只能停留在附近!

如果速度不取整,最后的结果就是停在目标值附近,还差几个像素,这个值最后算出来的速度的绝对值肯定小于1,导致还差几像素跨不过去了,如果你这时候让速度取整达到1,最后几个像素的距离其实就是匀速前行了,每次(30ms)都行走1px,因为最后几次都速度算出来都是1,1px 1px的行走到目的地!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS实现控制表格内指定单元格内容对齐的方法
Mar 30 Javascript
AngularJS手动表单验证
Feb 01 Javascript
jQuery实现table中的tr上下移动并保持序号不变的实例代码
Jul 11 Javascript
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
Dec 15 Javascript
详解Html a标签中href和onclick用法、区别、优先级别
Jan 16 Javascript
Vuex和前端缓存的整合策略详解
May 09 Javascript
vue component组件使用方法详解
Jul 14 Javascript
jquery操作ul的一些操作笔记整理(干货)
Aug 31 jQuery
node.js基于fs模块对系统文件及目录进行读写操作的方法详解
Nov 10 Javascript
Vue利用canvas实现移动端手写板的方法
May 03 Javascript
解决vue项目使用font-awesome,build后路径的问题
Sep 01 Javascript
微信小程序 自定义弹窗实现过程(附代码)
Dec 05 Javascript
深入理解Commonjs规范及Node模块实现
May 17 #Javascript
JavaScript限制在客户区可见范围的拖拽(解决scrollLeft和scrollTop的问题)(2)
May 17 #Javascript
vue学习笔记之vue1.0和vue2.0的区别介绍
May 17 #Javascript
Angular.JS中的this指向详解
May 17 #Javascript
websocket+node.js实现实时聊天系统问题咨询
May 17 #Javascript
JavaScript简单拖拽效果(1)
May 17 #Javascript
node.js连接MongoDB数据库的2种方法教程
May 17 #Javascript
You might like
PHP错误提示的关闭方法详解
2013/06/23 PHP
PHP实现的redis主从数据库状态检测功能示例
2017/07/20 PHP
jquery 图片Silhouette Fadeins渐显效果
2010/02/07 Javascript
jquery的Theme和Theme Switcher使用小结
2010/09/08 Javascript
javascript采用数组实现tab菜单切换效果
2012/12/12 Javascript
Jquery实现顶部弹出框特效
2015/08/08 Javascript
Webwork 实现文件上传下载代码详解
2016/02/02 Javascript
避免jQuery名字冲突 noConflict()方法
2016/07/30 Javascript
详解Angualr 组件间通信
2017/01/21 Javascript
jQuery EasyUI的TreeGrid查询功能实现方法
2017/08/08 jQuery
vue脚手架及vue-router基本使用
2018/04/09 Javascript
微信小程序顶部导航栏滑动tab效果
2019/01/28 Javascript
详解element-ui中form验证杂记
2019/03/04 Javascript
微信小程序swiper禁止用户手动滑动代码实例
2019/08/23 Javascript
jQuery擦除插件eraser使用方法详解
2020/01/11 jQuery
JS Array.from()将伪数组转换成数组的方法示例
2020/03/23 Javascript
vuex页面刷新导致数据丢失的解决方案
2020/12/10 Vue.js
js用正则表达式筛选年月日的实例方法
2021/01/04 Javascript
javascript实现数字时钟效果
2021/02/06 Javascript
Python实例之wxpython中Frame使用方法
2014/06/09 Python
处理Python中的URLError异常的方法
2015/04/30 Python
Python利用正则表达式匹配并截取指定子串及去重的方法
2015/07/30 Python
50行Python代码实现视频中物体颜色识别和跟踪(必须以红色为例)
2019/11/20 Python
Python数据存储之 h5py详解
2019/12/26 Python
python模拟实现斗地主发牌
2020/01/07 Python
Python GUI库PyQt5样式QSS子控件介绍
2020/02/25 Python
tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this T
2020/06/22 Python
CSS3实现翘边的阴影效果的代码示例
2016/06/13 HTML / CSS
比利时香水网上商店:NOTINO
2018/03/28 全球购物
社会公德演讲稿
2014/05/20 职场文书
法人代表授权委托书范文
2014/09/10 职场文书
导游词欢迎词
2015/02/02 职场文书
2015年小班保育员工作总结
2015/05/27 职场文书
低端且暴利的线上线下创业项目分享
2019/09/03 职场文书
mysql备份策略的实现(全量备份+增量备份)
2021/07/07 MySQL
解决IIS7下无法绑定https主机的问题
2022/04/29 Servers