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 相关文章推荐
jquery中.add()的使用分析
Apr 26 Javascript
jQuery的选择器中的通配符使用介绍
Mar 20 Javascript
jQuery判断checkbox是否选中的3种方法
Aug 12 Javascript
JavaScript实现可拖拽的拖动层Div实例
Aug 05 Javascript
JS实现为排序好的字符串找出重复行的方法
Mar 02 Javascript
微信小程序 教程之模板
Oct 18 Javascript
JS基于递归算法实现1,2,3,4,5,6,7,8,9倒序放入数组中的方法
Jan 03 Javascript
JS判断Android、iOS或浏览器的多种方法(四种方法)
Jun 29 Javascript
AngularJS ng-repeat指令及Ajax的应用实例分析
Jul 06 Javascript
利用javascript如何随机生成一定位数的密码
Sep 22 Javascript
详解如何在Vue项目中导出Excel
Apr 19 Javascript
解决vue的touchStart事件及click事件冲突问题
Jul 21 Javascript
原生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 array_multisort() 函数的深入解析
2013/06/20 PHP
PHP实现操作redis的封装类完整实例
2015/11/14 PHP
PHP获取文件扩展名的4种方法
2015/11/24 PHP
PHP实现的通过参数生成MYSQL语句类完整实例
2016/04/11 PHP
原生php实现excel文件读写的方法分析
2018/04/25 PHP
PHP中常见的密码处理方式和建议总结
2018/10/14 PHP
javascript面向对象之二 命名空间
2011/02/08 Javascript
javascript 基础篇4 window对象,DOM
2012/03/14 Javascript
中文路径导致unitpngfix.js不正常的解决方法
2013/06/26 Javascript
高效的获取当前元素是父元素的第几个子元素
2013/10/15 Javascript
js实现的GridView即表头固定表体有滚动条且可滚动
2014/02/19 Javascript
Js数组排序函数sort()介绍
2015/06/08 Javascript
基于JavaScript实现网页倒计时自动跳转代码
2015/12/28 Javascript
全面解析Bootstrap中transition、affix的使用方法
2016/05/30 Javascript
JS实现的点击表头排序功能示例
2017/03/27 Javascript
jQuery操作之效果详解
2017/05/19 jQuery
使用JavaScript实现表格编辑器(实例讲解)
2017/08/02 Javascript
JavaScript满天星导航栏实现方法
2018/03/08 Javascript
使用vue for时为什么要key【推荐】
2019/07/11 Javascript
js设计模式之代理模式及订阅发布模式实例详解
2019/08/15 Javascript
vue treeselect获取当前选中项的label实例
2020/08/31 Javascript
Python列表推导式的使用方法
2013/11/21 Python
Python对列表排序的方法实例分析
2015/05/16 Python
Flask框架的学习指南之制作简单blog系统
2016/11/20 Python
python sys.argv[]用法实例详解
2018/05/25 Python
python调用百度语音识别实现大音频文件语音识别功能
2018/08/30 Python
python图像和办公文档处理总结
2019/05/28 Python
Python 堆叠柱状图绘制方法
2019/07/29 Python
Windows下Anaconda安装、换源与更新的方法
2020/04/17 Python
django model 条件过滤 queryset.filter(**condtions)用法详解
2020/05/20 Python
python opencv实现简易画图板
2020/08/27 Python
Calzedonia美国官网:意大利风格袜子、打底裤和沙滩装
2018/07/19 全球购物
意大利火车票和铁路通行证专家:ItaliaRail
2019/01/22 全球购物
通信工程专业毕业生推荐信
2013/12/25 职场文书
个人廉洁自律总结
2015/03/06 职场文书
2015年保险公司个人工作总结
2015/05/22 职场文书