javascript匀速动画和缓冲动画详解


Posted in Javascript onOctober 20, 2016

关于网页中的动画,在css3中我们已经可以使用一些属性快速的做出来,但是有时候为了浏览器的兼容性我们还是需要使用js来制作网页中的动画。

使用js做动画最重要的一个函数就是setInterval函数,这里不再赘述,不懂可以直接百度用法。本文主要讲动画的原理已经在制作过程中的要点。

老规矩,先上代码,能直接看懂的可以节省时间。

html部分:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
  <meta charset="UTF-8"> 
  <title>move</title> 
  <link rel="stylesheet" href="move1.css"> 
</head> 
<body> 
  <input type="button" value="匀速移动" id="move1"> 
  <input type="button" value="渐变移动" id="move2"> 
  <div id="box1" class="box"></div> 
  <div id="box2" class="box"></div> 
  <script type="text/javascript" src="move1.js"></script> 
</body> 
</html>

css部分:

*{ 
  margin: 0px; 
  padding: 0px; 
} 
.box{ 
  width: 100px; 
  height: 100px; 
  background-color: green; 
  position: relative; 
  margin-top: 10px; 
}

js部分:

/** 
 * Created by siri on 2016/9/10. 
 */ 
window.onload=function () { 
  var btn1 = document.getElementById('move1'); 
  var btn2 = document.getElementById('move2'); 
  var box1 = document.getElementById('box1'); 
  var box2 = document.getElementById('box2'); 
  btn1.onclick = function () { 
    animate1(box1,500); 
  } 
  btn2.onclick = function () { 
    animate2(box2,500); 
  } 
  //匀速动画 
  function animate1(ele,target){ 
    //要用定时器,先清除定时器 
    //一个盒子只能有一个定时器,这样儿的话,不会和其他盒子出现定时器冲突 
    //而定时器本身讲成为盒子的一个属性 
    clearInterval(ele.timer); 
    //我们要求盒子既能向前又能向后,那么我们的步长就得有正有负 
    //目标值如果大于当前值取正,目标值如果小于当前值取负 
    var speed = target>ele.offsetLeft?3:-3; 
    ele.timer = setInterval(function () { 
      //在执行之前就获取当前值和目标值之差 
      var val = target - ele.offsetLeft; 
      ele.style.left = ele.offsetLeft + speed + "px"; 
      //目标值和当前值只差如果小于步长,那么就不能再前进了 
      //因为步长有正有负,所有转换成绝对值来比较 
      console.log(val); 
      if(Math.abs(val)<=Math.abs(speed)){ 
        ele.style.left = target + "px"; 
        clearInterval(ele.timer); 
 
      } 
    },30); 
  } 
 
  //缓动动画封装 
  function animate2(ele,target) { 
    clearInterval(ele.timer); //清楚历史定时器 
    ele.timer = setInterval(function () { 
      //获取步长 确定移动方向(正负值) 步长应该是越来越小的,缓动的算法。 
      var step = (target-ele.offsetLeft)/10; 
      //对步长进行二次加工(大于0向上取整,小于0项下取整) 
      step = step>0?Math.ceil(step):Math.floor(step); 
      //动画原理: 目标位置 = 当前位置 + 步长 
      console.log(step); 
      ele.style.left = ele.offsetLeft + step + "px"; 
      //检测缓动动画有没有停止 
      if(Math.abs(target-ele.offsetLeft)<=Math.abs(step)){ 
        ele.style.left = target + "px"; //直接移动指定位置 
        clearInterval(ele.timer); 
      } 
    },30); 
  } 
 
 
}

html和css基本就是为了我们的js部分搭框架,不讲太多,要注意的是,一定要对全局的margin和padding清零,否则的话他在计算的时候初始的margin和padding会影响计算,从而导致有时候运动不停止的情况。

javascript部分代码的解析在源码中已经很详细了,下面主要讲解原理。

匀速运动:

通过setInterval函数我们控制每多少毫秒运动的距离,然后在快要到达指定位置的时候,判断步长(每多少毫秒运动的距离)和此时和目标位置的距离,如果步长大于此时和目标位置的距离,则直接定位到目标位置,这样做是为了避免步长和总距离不是整数倍关系而产生最后到达位置和目标位置有差值的错误。

缓冲运动:

缓冲运动的基本函数是和匀速运动一样的,只是缓冲运动的步长我们是通过和目标位置的距离来确定的,这样我们的步长是不断变小的,从而实现缓冲运动的效果。在确定步长的时候我们使用Math.ceil和Math.floor对步长值进行取整是为了避免出现小数,因为如果出现小数后面最后到达的位置肯定是和目标位置有误差的。

注意事项:在每次移动开始前一定要使用clearInterval清除定时器。

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

Javascript 相关文章推荐
解析页面加载与js函数的执行 onload or ready
Dec 12 Javascript
JS判断表单输入是否为空(示例代码)
Dec 23 Javascript
JS实现浏览器状态栏文字闪烁效果的方法
Oct 27 Javascript
vue 打包后的文件部署到express服务器上的方法
Aug 09 Javascript
JS 中document.write()的用法和清空的原因浅析
Dec 04 Javascript
JavaScript循环遍历你会用哪些之小结篇
Sep 28 Javascript
详解Vue2.0组件的继承与扩展
Nov 23 Javascript
jQuery实现的点击图片居中放大缩小功能示例
Jan 16 jQuery
浅谈发布订阅模式与观察者模式
Apr 09 Javascript
vue接入腾讯防水墙代码
May 07 Javascript
layui表格设计以及数据初始化详解
Oct 26 Javascript
记一次vue跨域的解决
Oct 21 Javascript
js设置和获取自定义属性的方法
Oct 20 #Javascript
js阻止冒泡和默认事件(默认行为)详解
Oct 20 #Javascript
浅谈JS中String()与 .toString()的区别
Oct 20 #Javascript
详解javascript事件绑定使用方法
Oct 20 #Javascript
angular源码学习第一篇 setupModuleLoader方法
Oct 20 #Javascript
jQuery动态创建元素以及追加节点的实现方法
Oct 20 #Javascript
JS中动态创建元素的三种方法总结(推荐)
Oct 20 #Javascript
You might like
PHP下编码转换函数mb_convert_encoding与iconv的使用说明
2009/12/16 PHP
php session和cookie使用说明
2010/04/07 PHP
一个简单php扩展介绍与开发教程
2010/08/19 PHP
php一些错误处理的方法与技巧总结
2013/08/10 PHP
thinkPHP订单数字提醒功能的实现方法
2016/12/01 PHP
php实现查询功能(数据访问)
2017/05/23 PHP
layui数据表格自定义每页条数limit设置
2019/10/26 PHP
Thinkphp 框架扩展之Widget扩展实现方法分析
2020/04/23 PHP
PHP+Redis事务解决高并发下商品超卖问题(推荐)
2020/08/03 PHP
PHP中SESSION过期设置
2021/03/09 PHP
Js 获取Gridview选中行的内容操作步骤
2013/02/05 Javascript
不提示直接关闭网页窗口的JS示例代码
2013/12/17 Javascript
Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
js中动态创建json,动态为json添加属性、属性值的实例
2016/12/02 Javascript
详解vue.js根据不同环境(正式、测试)打包到不同目录
2018/07/13 Javascript
微信小程序带动画弹窗组件使用方法详解
2018/11/27 Javascript
webpack-mvc 传统多页面组件化开发详解
2019/05/07 Javascript
详解关于React-Router4.0跳转不置顶解决方案
2019/05/10 Javascript
jQuery删除/清空指定元素的所有子节点实例代码
2019/07/04 jQuery
JavaScript中的相等操作符使用详解
2019/12/21 Javascript
微信小程序 bindtap 传参的实例代码
2020/02/21 Javascript
python网络编程学习笔记(五):socket的一些补充
2014/06/09 Python
python实现的希尔排序算法实例
2015/07/01 Python
基于asyncio 异步协程框架实现收集B站直播弹幕
2016/09/11 Python
python实现简易通讯录修改版
2018/03/13 Python
Python 类的特殊成员解析
2018/06/20 Python
Python轻量级web框架bottle使用方法解析
2020/06/13 Python
HTML5自定义mp3播放器源码
2020/01/06 HTML / CSS
EJB包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的
2015/07/24 面试题
安阳殷墟导游词
2015/02/10 职场文书
2015年外联部工作总结
2015/04/03 职场文书
学校清洁工岗位职责
2015/04/15 职场文书
2015年社区矫正工作总结
2015/04/21 职场文书
python单元测试之pytest的使用
2021/06/07 Python
Python中使用ipython的详细教程
2021/06/22 Python
集英社今正式宣布 成立游戏公司“集英社Games”
2022/03/31 其他游戏