Javascript动画效果(1)


Posted in Javascript onOctober 11, 2016

前面我们介绍了Javascript的回到顶部效果,今天呢,我们对Javascript动画做进一步的研究。在这篇博文中我们只介绍简单的匀速运动、简单的缓冲运动和简单的多物体运动后面我们还会介绍任意值变化的运动、链式运动、同时运动,同时我们还会简单的封装一个运动插件并且还会将Javascript方法和jquery方法进行比较。

1、简单的匀速运动

下面我们介绍一个demo,鼠标移入,动画向右移动(即隐藏部分显示);鼠标离开,动画向左运动(继续隐藏)整个过程都是匀速的。有了前面回到顶部效果作为基础,这里主要讲解重要部分,先来看看代码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>demo1</title>
    <style type="text/css">
      body,div,span{
        margin: 0px;
        padding: 0px;
      }
      #div1{
        width: 200px;
        height: 200px;
        background: red;
        position: relative;
        left: -200px;
      }
      #share{
        width: 20px;
        height: 40px;
        background: blue;
        position: absolute;
        left: 200px;
        top: 75px;
      }
    </style>
    <script type="text/javascript">
      //一进来就加载
      window.onload = function(){
        //获取div
        var oDiv = document.getElementById('div1');
        //鼠标移入时执行函数
        oDiv.onmouseover = function(){
          startMove();
        }
        //鼠标移出时执行函数
        oDiv.onmouseout = function(){
          startMove1();
        }
      }
      //定义一个定时器
      var timer = null;
      function startMove(){
        //让它一进来的时候就把计时器清掉,避免后面引入多个计时器
        clearInterval(timer);
        var oDiv = document.getElementById('div1');
        //插入一个定时器
        timer = setInterval(function(){  
//         oDiv.style.left = oDiv.offsetLeft+10+'px';
//         //offsetLeft    当前left的值
//         //此时运行的结果为鼠标移上去后,一直在动,此时需要if进行判断
          if(oDiv.offsetLeft == 0){
            //当当前的left值为0的时候,清空计时器
            clearInterval(timer);
          }
          else{
            //当当前的left值不为0的时候,进行移动
            oDiv.style.left = oDiv.offsetLeft+10+'px';
          }
        },30)
      } 
       
      function startMove1(){
        clearInterval(timer);
        var oDiv = document.getElementById('div1');
        timer = setInterval(function(){
          if(oDiv.offsetLeft == -200){
            clearInterval(timer);
          }
          else{
            oDiv.style.left = oDiv.offsetLeft-10+'px';
          }
        },30)
      }
         
        //可以修改当前内容里面相同的部分
         
    </script>
  </head>
  <body>
    <div id="div1">
      <span id="share">
        分享
      </span>
    </div>
     
  </body>
</html>

在Javascript部分,我们发现有很多代码重复了,这时我们可以通过将不同的地方用参数的方法传进去,主要代码如下:

/*
 * 前面的onmouseover和onmouseout事件中分别改为
 * startMove(10,0);
 * startMove(-10,-200);
 * 后面再将  startMove和startMove1两个函数进行合并,代码如下:     
 */
function startMove(speed,iTarget){
  clearInterval(timer);
  var oDiv = document.getElementById('div1');
  timer = setInterval(function(){
    if(oDiv.offsetLeft == iTarget){
      clearInterval(timer);
    }
    else{
      oDiv.style.left = oDiv.offsetLeft+speed+'px';
    }
  },30)
}

此时我们还是会发现一个问题,就是,在功能相同的情况下,参数越少越好,这时我们要对我们之前的代码做进一步修改,因为iTarget是目标值,所以我们考虑将speed参数去掉,代码如下:

//考虑参数越少越好原则,可以去掉speed,同时,前面的onmouseover和onmouseout事件也应相应改变
function startMove(iTarget){
  clearInterval(timer);
  var oDiv = document.getElementById('div1');
  timer = setInterval(function(){
    //定义一个speed
    var speed = 0;
    //对speed进行判断
    if(oDiv.offsetLeft > iTarget){
      //当oDiv.offsetLeft > iTarget时,应该向左移动
      speed = -10;
    }
    else{
      speed = 10;
    }
     
    if(oDiv.offsetLeft == iTarget){
      clearInterval(timer);
    }
    else{
      oDiv.style.left = oDiv.offsetLeft+speed+'px';
    }
  },30)
}

到这里,我们的匀速运动效果基本完成。在上面的demo中,我们改变的是left效果,同理我们还可以改变right,width和height效果。思考:在css3动画中有改变透明度的效果,在这里我们是否可以通过前面的方式来得到实现呢?
答案:大致可以用上面的方法去实现,但是有个小小的问题值得注意,无论是left,right还是width,height它们都有单位px(在上面的demo中,有一行代码就是这样:oDiv.style.left = oDiv.offsetLeft+speed+'px';),而透明度无论是opacity也好,是filter也好,它们都是没有单位的,故我们可以写如下代码:

alpha += speed;
oDiv.style.filter = 'alpha(opacity:'+alpha+')';
oDiv.style.opacity = alpha/100;

完整代码如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>demo2</title>
    <style type="text/css">
      body,div{
        margin: 0px;
        padding: 0px;
      }
      #div1{
        width: 200px;
        height: 200px;
        background: red;
        filter: alpha(opacity:30);
        opacity: 0.3;
      }
    </style>
    <script type="text/javascript">
      window.onload = function(){
        var oDiv = document.getElementById('div1');
        oDiv.onmouseover = function(){
          startMove(100);   //鼠标移入的时候,透明度为100%
        }
        oDiv.onmouseout = function(){
          startMove(30);   //鼠标移出的时候,透明度为30%
        }
      }
      var timer = null;
      var alpha = 30;
      function startMove(iTarget){
        var oDiv = document.getElementById('div1');
        clearInterval(timer);    //在运行之前,先关闭定时器
        //关了定时器后,现在运行时需要加定时器
        timer = setInterval(function(){
          var speed = 0;
          if(alpha > iTarget){
            speed = -10;
          }
          else{
            speed = 10
          }
          if(alpha == iTarget){
            clearInterval(timer);
          }
          else{
            alpha += speed;
            oDiv.style.filter = 'alpha(opacity:'+alpha+')';
            oDiv.style.opacity = alpha/100;
          }
        },30)       
      }
       
    </script>
  </head>
  <body>
    <div id="div1">
      要求:
      <p>鼠标移入,透明度为100%;鼠标移出,透明度为30%</p>
    </div>
  </body>
</html>

到这里,我们的速度动画就告一段落了。关于opacity和filter,详情请见这里

2、缓冲运动

回忆之前回到顶部效果,为了增加用户的体验效果,回到顶部时是先快后慢。有了前面的基础,这里句很好办了,以demo1为例,我们可以添加如下代码:

function startMove(iTarget){
        var oDiv = document.getElementById('div1');
        clearInterval(timer);
        timer = setInterval(function(){
          var speed = (iTarget - oDiv.offsetLeft)/20;
          speed = speed>0?Math.ceil(speed):Math.floor(speed);
          //注意这里的取整问题,不然运动后回不到原来的位置
//         if(speed > 0){
//           speed = Math.ceil(speed);
//         }
//         else{
//           speed = Math.floor(speed);
//         }
          if(iTarget == oDiv.offsetLeft){
            clearInterval(timer);
          }
          else{
            oDiv.style.left = oDiv.offsetLeft+speed+'px';
          }
        },30)
      }

在这段代码中,var speed = (iTarget - oDiv.offsetLeft)/20;通过控制被除数可以控制动画的速度,然后我们分别用Math.floor和Math.ceil分别进行向下和向上取整,如果没用取整,那么鼠标移入和移出都达不到想要的效果(计算机在进行计算时总是有误差的)。到这里,缓冲运动也介绍的差不多了。下面我们来介绍多物体运动。

3、多物体运动

有了前面的基础,我们来看多物体运动时就觉得简单了。在多物体运动中,我们将宽度变化和透明度变化分开来讲
【多物体宽度变化】
在多物体宽度变化中,我们用无序列表来实现。与单个物体宽度变化不同的是,我们要用for循环依次遍历我们想要的值,关键代码如下:

var aLi = document.getElementsByTagName('li');
for(var i = 0; i< aLi.length; i++){   //i=0
  aLi[i].onmouseover = function(){
    startMove(this,400);
  }
  aLi[i].onmouseout = function(){
    startMove(this,200);
  }
}

全代码如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>多物体动画</title>
    <style type="text/css">
      body,ul,li{
        margin: 0px;
        padding: 0px;
      }
      ul,li{
        list-style: none;
      }
      ul li{
        width: 200px;
        height: 100px;
        background: yellow;
        margin-bottom: 20px;
      }
    </style>
    <script type="text/javascript">
      window.onload = function(){
        var aLi = document.getElementsByTagName('li');
        for(var i = 0; i< aLi.length; i++){   //i=0
          aLi[i].timer = null;
          aLi[i].onmouseover = function(){
            startMove(this,400);//this指向当前的aLi[i].onmouseover事件
          }
          aLi[i].onmouseout = function(){
            startMove(this,200);//this指向当前的aLi[i].onmouseout事件
          }
        }
         
      }
       
      //var timer = null;
      /*
       * 若该代码还是在这里,当鼠标依次缓慢经过时不会出现大的问题,但是当移动的速度比较快时,会发现有问题:可以变得越来越宽
       * 原因:timer并不是每次在鼠标经过每一个区域时为null
       * 解决办法:在前面的for循环中加上aLi[i].timer = null;这样每次执行前都是null开始
       */     
 
      function startMove(obj,iTarget){//因为li有多个,这里需要再传一个参数obj
        //var aLi = document.getElementsByTagName('li');
        clearInterval(obj.timer);
        obj.timer = setInterval(function(){
          var speed = (iTarget - obj.offsetWidth)/10;
          speed = speed>0?Math.ceil(speed):Math.floor(speed);
          if(iTarget == obj.offsetWidth){
            clearInterval(obj.timer);
          }
          else{
            obj.style.width = obj.offsetWidth+speed+'px';
            //是obj 不是 aLi
          }
        },30)
      }
    </script>
  </head>
  <body>
    <ul>
      <li></li>
      <li></li>
      <li></li>
    </ul>
  </body>
</html>

【多物体透明度动画】
有了上面的例子,我们就能很容易的写出多物体透明度动画的代码,代码如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>多物体透明度动画</title>
    <style type="text/css">
      body,div{
        margin: 0px;
        padding: 0px;
      }
      div{
        width: 200px;
        height: 200px;
        background: red;
        margin: 10px;
        float: left;
        filter:alpha(opacity:30);
        opacity:0.3;
      }
    </style>
    <script type="text/javascript">
      window.onload = function(){
        var oDiv = document.getElementsByTagName('div');
        for(var i=0;i<oDiv.length;i++){
          oDiv[i].timer = null;
          oDiv[i].alpha = 30;
          oDiv[i].onmouseover = function(){
            startMove(this,100);
          }
          oDiv[i].onmouseout = function(){
            startMove(this,30);
          }
        }       
      }
      //var alpha = 30;
      function startMove(obj,iTarget){
        clearInterval(obj.timer);
        obj.timer = setInterval(function(){
          var speed = 0;
          if(iTarget > obj.alpha){
            speed = 10;
          }
          else{
            speed = -10;
          }
          if(iTarget == obj.alpha){
            clearInterval(obj.timer);
          }
          else{
            obj.alpha +=speed;
            obj.style.filter = 'obj.alpha(opacity:'+obj.alpha+')';
            obj.style.opacity = obj.alpha/100;
          }
        },30)
      }
    </script>
  </head>
  <body>
    <div id="div1"></div>
    <div id="div2"></div>
    <div id="div3"></div>
    <div id="div4"></div>
  </body>
</html>

和之前的timer一样,alpha = 30;也需要写在for循环的后面。
到这里,简单的动画效果就告一段落了,慢慢的一步一步的去修改去尝试就会有新的发现。

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

Javascript 相关文章推荐
javascript 函数式编程
Aug 16 Javascript
JS实现标签页效果(配合css)
Apr 03 Javascript
jQuery选择器之基本选择器与层次选择器
Mar 03 Javascript
jQuery判断元素上是否绑定了指定事件的方法
Mar 17 Javascript
详解基于 axios 的 Vue 项目 http 请求优化
Sep 04 Javascript
JS模拟实现哈希表及应用详解
May 04 Javascript
一个Vue页面的内存泄露分析详解
Jun 25 Javascript
解决vue-quill-editor上传内容由于图片是base64的导致字符太长的问题
Aug 20 Javascript
JS左右无缝轮播功能完整实例
May 16 Javascript
vue滚动插件better-scroll使用详解
Oct 18 Javascript
jquery实现拖拽小方块效果
Dec 10 jQuery
vue postcss-px2rem 自适应布局
May 15 Vue.js
原生Javascript和jQuery做轮播图简单例子
Oct 11 #Javascript
jQuery progressbar通过Ajax请求实现后台进度实时功能
Oct 11 #Javascript
javascript之with的使用(阿里云、淘宝使用代码分析)
Oct 11 #Javascript
Node.js的文件权限及读写flag详解
Oct 11 #Javascript
最原始的jQuery注册验证方式
Oct 11 #Javascript
js正则表达式注册页面表单验证
Oct 11 #Javascript
jQuery ajax MD5实现用户注册即时验证功能
Oct 11 #Javascript
You might like
PHP数据类型之布尔型的介绍
2013/04/28 PHP
PHP获取服务器端信息的方法
2014/11/28 PHP
php查询mysql大量数据造成内存不足的解决方法
2015/03/04 PHP
PHP中SERIALIZE和JSON的序列化与反序列化操作区别分析
2016/10/11 PHP
PHP钩子与简单分发方式实例分析
2017/09/04 PHP
jQuery简单图表peity.js使用示例
2014/05/02 Javascript
javascript面向对象快速入门实例
2015/01/13 Javascript
JS仿Windows开机启动Loading进度条的方法
2015/02/26 Javascript
如何实现JavaScript动态加载CSS和JS文件
2020/12/28 Javascript
浅谈JS中的bind方法与函数柯里化
2016/08/10 Javascript
jQuery实现的tab标签切换效果示例
2016/09/05 Javascript
微信小程序 for 循环详解
2016/10/09 Javascript
Angular2从搭建环境到开发步骤详解
2016/10/17 Javascript
vue.js利用defineProperty实现数据的双向绑定
2017/04/28 Javascript
详解Angular2组件之间如何通信
2017/06/22 Javascript
详解使用 Node.js 开发简单的脚手架工具
2018/06/08 Javascript
在angularJs中进行数据遍历的2种方法
2018/10/08 Javascript
mpvue全局引入sass文件的方法步骤
2019/03/06 Javascript
微信小程序官方动态自定义底部tabBar的例子
2019/09/04 Javascript
JavaScript中作用域链的概念及用途讲解
2020/08/06 Javascript
python使用循环实现批量创建文件夹示例
2014/03/25 Python
Python下的Mysql模块MySQLdb安装详解
2014/04/09 Python
python引入导入自定义模块和外部文件的实例
2017/07/24 Python
使用Python实现博客上进行自动翻页
2017/08/23 Python
python实现requests发送/上传多个文件的示例
2018/06/04 Python
django中forms组件的使用与注意
2019/07/08 Python
tensorflow指定GPU与动态分配GPU memory设置
2020/02/03 Python
HTML5微信播放全屏问题的解决方法
2017/03/09 HTML / CSS
中国领先的汽车保养服务平台:途虎养车
2019/10/18 全球购物
电气工程师岗位职责
2014/01/01 职场文书
实习老师离校感言
2014/02/03 职场文书
四风问题个人对照检查剖析材料
2014/09/27 职场文书
私人房屋买卖协议书
2014/10/04 职场文书
环境卫生标语
2015/08/03 职场文书
老干部局2015年度工作总结
2015/10/22 职场文书
python百行代码实现汉服圈图片爬取
2021/11/23 Python