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 相关文章推荐
Some tips of wmi scripting in jscript (1)
Apr 03 Javascript
jQuery之日期选择器的深入解析
Jun 19 Javascript
jquery动态改变onclick属性导致失效的问题解决方法
Dec 04 Javascript
jQuery实现根据类型自动显示和隐藏表单
Mar 18 Javascript
JQuery实现Ajax加载图片的方法
Dec 24 Javascript
javascript 判断页面访问方式电脑或者移动端
Sep 19 Javascript
vue.js实现仿原生ios时间选择组件实例代码
Dec 21 Javascript
Vue实现PopupWindow组件详解
Apr 28 Javascript
原生JS实现的简单轮播图功能【适合新手】
Aug 17 Javascript
详解angularjs跨页面传参遇到的一些问题
Nov 01 Javascript
利用Angular7开发一个Radio组件的全过程
Jul 11 Javascript
微信小程序批量上传图片到七牛(推荐)
Dec 19 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学习之php4与php5之间会穿梭一点点感悟
2007/05/03 PHP
php生成缩略图填充白边(等比缩略图方案)
2013/12/25 PHP
ecshop实现smtp发送邮件
2015/02/03 PHP
Thinkphp5+uploadify实现的文件上传功能示例
2018/05/26 PHP
自定义Laravel (monolog)日志位置,并增加请求ID的实现
2019/10/17 PHP
Javascript 遮罩层和加载效果代码
2013/08/01 Javascript
js获取select标签的值且兼容IE与firefox
2013/12/30 Javascript
jQuery响应enter键的实现思路
2014/04/18 Javascript
js获取网页可见区域、正文以及屏幕分辨率的高度
2014/05/15 Javascript
分享JS数组求和与求最大值的方法
2016/08/11 Javascript
Javascript中常用的检测方法小结
2016/10/08 Javascript
类似于QQ的右滑删除效果的实现方法
2016/10/16 Javascript
VueJs路由跳转——vue-router的使用详解
2017/01/10 Javascript
Vue2学习笔记之请求数据交互vue-resource
2017/02/23 Javascript
JS分页的实现(同步与异步)
2017/09/16 Javascript
vue 的keep-alive缓存功能的实现
2018/03/22 Javascript
vue和webpack打包项目相对路径修改的方法
2018/06/15 Javascript
Vue+Java+Base64实现条码解析的示例
2020/09/23 Javascript
[01:08:17]2018DOTA2亚洲邀请赛3月29日 小组赛B组 EG VS VGJ.T
2018/03/30 DOTA
实例Python处理XML文件的方法
2015/08/31 Python
实例讲解Python设计模式编程之工厂方法模式的使用
2016/03/02 Python
Python 爬虫学习笔记之多线程爬虫
2016/09/21 Python
python2.7实现爬虫网页数据
2018/05/25 Python
搞定这套Python爬虫面试题(面试会so easy)
2019/04/03 Python
Python实现括号匹配方法详解
2020/02/10 Python
HTML5 在canvas中绘制文本附效果图
2014/06/23 HTML / CSS
Sport-Thieme荷兰:购买体育用品
2019/08/25 全球购物
生日寿宴答谢词
2014/01/19 职场文书
校园十佳歌手策划书
2014/01/22 职场文书
大学毕业自我评价
2014/02/02 职场文书
大学生个人自荐信样本
2014/03/02 职场文书
作文评语集锦大全
2014/04/23 职场文书
群众路线党员个人剖析材料
2014/10/08 职场文书
会计主管岗位职责
2015/04/02 职场文书
Golang中interface{}转为数组的操作
2021/04/30 Golang
windows server2016安装oracle 11g的图文教程
2022/07/15 Servers