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 相关文章推荐
JS 使用for循环遍历子节点查找元素
Sep 06 Javascript
jQuery使用before()和after()在元素前后添加内容的方法
Mar 26 Javascript
jQuery基于ajax实现星星评论代码
Aug 07 Javascript
JS简单实现数组去重的方法示例
Mar 27 Javascript
详解node-ccap模块生成captcha验证码
Jul 01 Javascript
javascript 取小数点后几位几种方法总结
Aug 02 Javascript
vue.js todolist实现代码
Oct 29 Javascript
React中嵌套组件与被嵌套组件的通信过程
Jul 11 Javascript
详解vue.js下引入百度地图jsApi的两种方法
Jul 27 Javascript
VUE实现Studio管理后台之鼠标拖放改变窗口大小
Mar 04 Javascript
微信小程序中wxs文件的一些妙用分享
Feb 18 Javascript
Vue3如何理解ref toRef和toRefs的区别
Feb 18 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 CURL 多线程操作代码实例
2015/05/13 PHP
javascript小数计算出现近似值的解决办法
2010/02/06 Javascript
Javascript面向对象编程(二) 构造函数的继承
2011/08/28 Javascript
jQuery1.9.1针对checkbox的调整方法(prop)
2014/05/01 Javascript
判断浏览器的内核及版本号方法汇总
2015/01/05 Javascript
使用js实现的简单拖拽效果
2015/03/18 Javascript
AngularJS基础学习笔记之表达式
2015/05/10 Javascript
简介JavaScript中setUTCSeconds()方法的使用
2015/06/12 Javascript
javascript实现控制的多级下拉菜单
2015/07/05 Javascript
快速掌握Node.js中setTimeout和setInterval的使用方法
2016/03/21 Javascript
AngularJS的依赖注入实例分析(使用module和injector)
2017/01/19 Javascript
利用JS做网页特效_大图轮播(实例讲解)
2017/08/09 Javascript
NodeJS使用Range请求实现下载功能的方法示例
2018/10/12 NodeJs
如何解决日期函数new Date()浏览器兼容性问题
2019/09/11 Javascript
Python3.0与2.X版本的区别实例分析
2014/08/25 Python
简单理解Python中基于生成器的状态机
2015/04/13 Python
Android基于TCP和URL协议的网络编程示例【附demo源码下载】
2018/01/23 Python
python实现微信远程控制电脑
2018/02/22 Python
用Anaconda安装本地python包的方法及路径问题(图文)
2019/07/16 Python
使用python获取邮箱邮件的设置方法
2019/09/20 Python
利用Python实现Excel的文件间的数据匹配功能
2020/06/16 Python
CSS3中currentColor关键字的妙用
2016/02/27 HTML / CSS
携程英文网站:Trip.com
2017/02/07 全球购物
探索欧洲最好的品牌:Bombinate
2019/06/14 全球购物
劳资员岗位职责
2013/11/11 职场文书
会计实习自我鉴定
2013/12/04 职场文书
电子信息专业自荐书
2014/02/04 职场文书
《纸船和风筝》教学反思
2014/02/15 职场文书
民生工程实施方案
2014/03/22 职场文书
质量主管工作职责
2014/09/26 职场文书
2014最新自愿离婚协议书范本
2014/11/19 职场文书
党员争先创优承诺书
2015/01/20 职场文书
2015年美容师个人工作总结
2015/10/14 职场文书
《牧场之国》教学反思
2016/02/22 职场文书
Python Pygame实战之塔防游戏的实现
2022/03/17 Python
vue route新窗口跳转页面并且携带与接收参数
2022/04/10 Vue.js