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 相关文章推荐
JavaScript 参考教程
Dec 29 Javascript
Prototype使用指南之string.js
Jan 10 Javascript
IE和Firefox下event事件杂谈
Dec 18 Javascript
JS获取农历日期具体实例
Nov 14 Javascript
jQuery 获取遍历获取table中每一个tr中的第一个td的方法
Oct 05 Javascript
jquery插入兄弟节点的操作方法
Dec 07 Javascript
node.js实现复制文本到剪切板的功能
Jan 23 Javascript
JS闭包用法实例分析
Mar 27 Javascript
js实现倒计时器自定义时间和暂停
Feb 25 Javascript
Flutter实现仿微信底部菜单栏功能
Sep 18 Javascript
微信小程序实现多选框功能的实例代码
Jun 24 Javascript
JS时间戳与日期格式互相转换的简单方法示例
Jan 30 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
php4的session功能评述(二)
2006/10/09 PHP
php UNIX时间戳用法详解
2017/02/16 PHP
动态加载图片路径 保持JavaScript控件的相对独立性
2010/09/03 Javascript
jquery 页眉单行信息滚动显示实现思路及代码
2014/06/26 Javascript
Firefox下无法正常显示年份的解决方法
2014/09/04 Javascript
JavaScript中setFullYear()方法的使用详解
2015/06/11 Javascript
chrome下判断点击input上标签还是其余标签的实现方法
2016/09/18 Javascript
运用jQuery写的验证表单(实例讲解)
2017/07/06 jQuery
一步步教会你微信小程序的登录鉴权
2018/04/09 Javascript
axios+Vue实现上传文件显示进度功能
2019/04/14 Javascript
vue 的 solt 子组件过滤过程解析
2019/09/07 Javascript
JavaScript监听触摸事件代码实例
2019/12/30 Javascript
Python实现列表转换成字典数据结构的方法
2016/03/11 Python
Python使用matplotlib简单绘图示例
2018/02/01 Python
python引入不同文件夹下的自定义模块方法
2018/10/27 Python
解决Python列表字符不区分大小写的问题
2019/12/19 Python
pytorch 修改预训练model实例
2020/01/18 Python
python图形开发GUI库pyqt5的详细使用方法及各控件的属性与方法
2020/02/14 Python
Pycharm如何运行.py文件的方法步骤
2020/03/03 Python
Python代码一键转Jar包及Java调用Python新姿势
2020/03/10 Python
Python函数基本使用原理详解
2020/03/19 Python
使用卷积神经网络(CNN)做人脸识别的示例代码
2020/03/27 Python
Python中Qslider控件实操详解
2021/02/20 Python
Python实现图片指定位置加图片水印(附Pyinstaller打包exe)
2021/03/04 Python
利用html5 canvas动态画饼状图的示例代码
2018/04/02 HTML / CSS
详解移动端HTML5页面端去掉input输入框的白色背景和边框(兼容Android和ios)
2016/12/15 HTML / CSS
优质美利奴羊毛袜,不只是徒步旅行:Darn Tough Vermont
2018/11/05 全球购物
英国在线药房:Chemist.co.uk
2019/03/26 全球购物
navabi英国:设计师大码女装
2019/06/25 全球购物
奥地利购买珠宝和手表网站:ELLA JUWELEN
2019/09/03 全球购物
在购买印度民族服饰:Soch
2020/09/15 全球购物
开业庆典答谢词
2014/01/18 职场文书
法学个人求职信范文
2014/01/27 职场文书
咖啡蛋糕店创业计划书
2014/01/28 职场文书
数控技术学生的自我评价
2014/02/15 职场文书
手机被没收检讨书
2014/02/22 职场文书