Javascript动画效果(3)

前面我们已经介绍了速度动画、透明度动画、多物体运动和任意值变化,并且我们在Javascript动画效果(二)中介绍到我们封装了一个简单的插件雏形,接下来我们对前面的动画效果进行进一步扩充,尽量将我们的框架做到更实用。在这里我们还需要了解两个运动,一个是链式运动,一个是同时运动。它们间的区别分别是:链式运动是指运动一个接着一个(一个运动完成马上进行下一个运动);而同时运动是指所有的运动同时进行。在这里,我们该如何实现呢?

1、链式运动

  前面的效果中,我们已经能对任意值进行相应的变化,我们该如何在一个动画后添加一个动画呢?

  思路:我们能不能在参数中传入一个函数,当一个效果完成后马上执行后面的函数(效果),该函数可以是想要的动画效果

  实现:在function startMove(obj,attr,iTarget)中在传入一个参数fn,代表一个函数。这时我们还需要修改的有在定时器的后面增加一个判断if(fn){fn(); },当存在fn函数时执行fn函数,当不存在fn函数时清除定时器。这样我们的window.onload函数也应该发生相应变化,代码如下:

window.onload = function() {
  var Li = document.getElementById('li1');
  Li.onmouseover = function() {
    startMove(Li, 'width', 400, function() {
      startMove(Li, 'height', 200, function() {
        startMove(Li, 'opacity', 100);
      });
    });
  };
  Li.onmouseout = function() {
    startMove(Li, 'opacity', 30, function() {
      startMove(Li, 'height', 100, function() {
        startMove(Li, 'width', 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; border: 4px solid #000; filter:alpha(opacity:30); opacity:0.3; }
    </style>

  </head>
  <body>
    <ul>
      <li id="li1"></li>
    </ul>
    <script type="text/javascript">
      window.onload = function(){
        var Li = document.getElementById('li1');
        Li.onmouseover = function(){
          startMove(Li,'width',400,function(){
            startMove(Li,'height',200,function(){
              startMove(Li,'opacity',100);
            });
          });
        };
        Li.onmouseout = function(){
          startMove(Li,'opacity',30,function(){
            startMove(Li,'height',100,function(){
              startMove(Li,'width',200);
            });
          });
        };
      };

      function startMove(obj,attr,iTarget,fn){
        clearInterval(obj.timer);
        obj.timer = setInterval(function(){
          var icur = 0;
          if(attr == 'opacity'){
            icur = Math.round(parseFloat(getStyle(obj,attr))*100);
          }else{
            icur = parseInt(getStyle(obj,attr));
          }
          var speed = (iTarget - icur)/10;
          speed = speed>0?Math.ceil(speed):Math.floor(speed);
          if(iTarget == icur){
            clearInterval(obj.timer);
            if(fn){
              fn();
            }
          }
          else{
            if(attr == 'opacity'){
              obj.style.filter = 'alpha(opacity:'+(icur+speed)+')';
              obj.style.opacity = (icur+speed)/100;
            }
            else{
              obj.style[attr] = icur+speed+'px';
            }
          }
        },30)
      }   

      function getStyle(obj,attr){
        if(obj.currentStyle){
          return obj.currentStyle[attr];
        }
        else{
          return getComputedStyle(obj,false)[attr];
        }
      }
    </script>
  </body>
</html>

2、同时运动

说到同时运动,你可能会觉得很简单,直接在onmouseover事件后面同时添加两个不同的starMove()函数就可以解决了(错误思路!),实际上并不是这样的,当有多个效果时,我们看到的是最后添加的那个效果。也就是说我们想同时改变宽度和高度(高度在后),我们得到的效果为只改变高度,宽度并没有变化。这里我们应该继续传参数么?从链式运动来看,传参数的效果只能在后面添加函数得到连续的动画效果。

  思路:我们可不可以用JSON的方法来同时改变多个动画效果?

  实现:将function startMove(obj,attr,iTarget,fn)中的attr和iTarget合并为一个参数:json,我们用for/in的方法来遍历json中的数据,例如:

var json = {"a":12,"b":21};
for(var attr in json){
  alert(json);//结果分别是:a,b
  alert(json[attr]);//结果分别是:12,21
}

按照此方法,我们依次改变前面的代码:在定时器函数的后面加上代码:for(var attr in json) {...},并且修改里面的iTarget为json[attr],再将window.onload函数修改为:

window.onload = function() {
  var Li = document.getElementById('li1');
  Li.onmouseover = function() {
    startMove(Li, {
      width: 400,
      height: 200,
      opacity: 100
    });
  };
  Li.onmouseout = function() {
    startMove(Li, {
      width: 200,
      height: 100,
      opacity: 30
    });
  };
};

这时我们差不多就可以得到我们想要的效果了,但是这样离我们最终的效果还是查了那么一点点,比如说我们将onmouseover事件中的starMove中的width修改为202,再执行我们的代码,我们会发现最终的height不是200px,opacity也不是100,如图:

这样就很尴尬了,之前我们的效果不是还蛮好的么?我们再回到我们的JS代码中分析结构,觉得最有可能出错的就是starMove函数中,我们发现这段代码的意思有点难理解:

if(json[attr] == icur) {
  clearInterval(obj.timer);
  if(fn) {
    fn();
  }
}

我们并不知道是不是所有的运动都到达终点时停止所有运动还是当只有一个运动达到终点时立马停止所有运动。但是通过我们前面的操作,可以知道的实际结果为,只有一个运动到达终点值时,所有的运动都停止了(此时还有运动没执行完),我们该如何进行操作呢?

  思路:我们可以假定一个参数flag,并且赋值为true,在执行clearInterval(obj.timer);操作前我们先进行判断if(json[attr] != icur) { flag = false;},后面执行之前else里面的语句,再执行如下语句if(flag = true) {clearInterval(obj.timer); if(fn) {fn();}},这样我们就可以得到同时运动的完整代码如下:

<!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; border: 4px solid #000; filter:alpha(opacity:30); opacity:0.3; }
    </style>

  </head>
  <body>
    <ul>
      <li id="li1"></li>
    </ul>

    <script type="text/javascript">
      window.onload = function(){
        var Li = document.getElementById('li1');
        Li.onmouseover = function(){
          startMove(Li,{width:202,height:200,opacity:100});
        };
        Li.onmouseout = function(){
          startMove(Li,{width:200,height:100,opacity:30});
        };
      };

      function getStyle(obj, attr) {
        if(obj.currentStyle) {
          return obj.currentStyle[attr];
        } else {
          return getComputedStyle(obj, false)[attr];
        }
      }

      function startMove(obj, json, fn) {
        //定义标杆
        var flag = true; //假设的

        clearInterval(obj.timer);
        obj.timer = setInterval(function() {
          for(var attr in json) {
            var icur = 0;
            if(attr == 'opacity') {
              icur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
            } else {
              icur = parseInt(getStyle(obj, attr));
            }
            var speed = (json[attr] - icur) / 10;
            speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
            if(json[attr] != icur) {
              flag = false;
            }
            if(attr == 'opacity') {//判断是否为opacity
              obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')';
              obj.style.opacity = (icur + speed) / 100;
            } else {
              obj.style[attr] = icur + speed + 'px';
            }
            if(flag){
              clearInterval(obj.timer);
              if(fn){
                fn();
              }
            }
          }
        }, 30)
      }
    </script>
  </body>
</html>

这样我们的同时运动的动画效果就实现了。在这里,你有没有觉得很神奇?

在这里我们已经将一个简单的运动插件封装完成了,我们将里面的代码做一些解释,并且将它保存为一个foodoir.animate.js文件,代码如下:

/*
 * 简单的运动框架
 * 作者:foodoir
 * 此框架仅作参考!!!
 *
 * 使用方法见博文
 */

function getStyle(obj, attr) {
  if(obj.currentStyle) {
    return obj.currentStyle[attr];
  } else {
    return getComputedStyle(obj, false)[attr];
  }
}

function startMove(obj, json, fn) {

  clearInterval(obj.timer); //清除定时器,避免重复生成多个定时器
  obj.timer = setInterval(function() {
    var flag = true; //假设刚开始时所有运动都已完成
    for(var attr in json) { //遍历json

      var icur = null;
      //1.判断类型
      if(attr == 'opacity') {
        icur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
      } else {
        icur = parseInt(getStyle(obj, attr));
      }
      //2.算速度
      var speed = (json[attr] - icur) / 5;
      speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
      //3.检测停止
      if(icur != json[attr]) {
        flag = false;
      }
      if(attr == 'opacity') {
        obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')';
        obj.style.opacity = (icur + speed) / 100;
      } else {
        obj.style[attr] = icur + speed + 'px';
      }
    }
    if(flag) { //当所有运动都完成时,清除定时器
      clearInterval(obj.timer);
      if(fn) {
        fn();
      }
    }
  }, 30);
}

后面,我们将介绍用自己的框架来实现多种动画效果,并且和jquery中的动画效果进行比较。

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

(0)

相关推荐

  • java用户管理注册功能 含前后台代码

    本文实例为大家分享了java用户注册功能,供大家参考,具体内容如下 主页面: 浏览器显示: 代码实现: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <title>用户信息管理</title> </head> <body> 用户注册:<br

  • java书店系统毕业设计 用户模块(2)

    本文实例为大家分享了java书店系统毕业设计第二篇,供大家参考,具体内容如下 1.用户管理(user.txt) 字段名和顺序 说明:其中的type为int类型,用来表示操作用户的类型. 1--表示为admin,可以进行全部操作 2--表示为能操作图书模块的人员 3--表示为能操作进货模块的人员 4--表示为能操作销售模块的人员 5--表示为能操作库存模块的人员 type用了枚举实现 package cn.hncu.bookStore.user.common; public enum UserTy

  • Java 常见异常(Runtime Exception )详细介绍并总结

    本文重在Java中异常机制的一些概念.写本文的目的在于方便我很长时间后若是忘了这些东西可以通过这篇文章迅速回忆起来. 1. 异常机制 1.1 异常机制是指当程序出现错误后,程序如何处理.具体来说,异常机制提供了程序退出的安全通道.当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器. 1.2 传统的处理异常的办法是,函数返回一个特殊的结果来表示出现异常(通常这个特殊结果是大家约定俗称的),调用该函数的程序负责检查并分析函数返回的结果.这样做有如下的弊端:例如函数返回-1代表出现异常

  • java实现 微博登录、微信登录、qq登录实现代码

    微信,微博,QQ,这是现在目前用的最多的手机 APP,我们做产品哪能不跟他们不沾边,对于登录,我想谁也不想要多少个帐号密码,根本记不住! 为了增加用户体验,用户能够快速的注册登录,第三方账号进行登录注册的的需求也就由此而诞生 1.微信 1) 微信登录也是最坑人的,需要花300大洋成为开发者账户,没办法谁让微信用户群体大呢所以也就只好认了:然后登录网站后台需要创建网站应用,填写授权回调域(登录网站的域名)只填写域名即可 申请地址: https://open.weixin.qq.com/cgi-bi

  • java表单提交中文乱码的解决方法

    本文实例为大家分享了java表单提交中文乱码的解决方法,供大家参考,具体内容如下 主页index.xml <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <title>servlet演示</title> </head> <body> <h2&

  • Java 模拟银行自助终端系统

    一. 本系统模拟银行用户使用ATM机开户.查询.存款.取款功能,要求使用java语言编程实现. 说明: 1. 对于数据输入异常,可使用java异常处理机制进行处理. 2. 评分将以功能实现与代码规范性相结合的方式进行考核. 3. 如果对项目需求有疑问,可以随时以QQ留言方式联系我进行咨询. 4. 国庆放假期间,每天都有老师在公司值班,10月4日是我在公司值班,10月7日正常上班,欢迎大家到公司来做项目. 二. 项目功能要求: 项目开始运行显示主菜单为: 银行自助终端系统 ************

  • Javascript动画效果(2)

    在前面的文章中讲了简单的Javascript动画效果,这篇文章主要介绍我在改变之前代码时发现的一些问题及解决方法. 在前面的多物体宽度变化的例子中,我们给其增加代码:border: 4px solid #000;我们发现,鼠标移出后,宽度不是200px了,那么究竟是如何产生这种情况的呢?下面我们通过一个新的例子来分析 html代码: <div id="div1">hello</div> css代码: body,div{ margin: 0px; padding:

  • AngularJS 实现JavaScript 动画效果详解

    AngularJS 应用中实现 JavaScript 动画效果 AngularJS 是一组用于创建单页Web应用的丰富框架,给构建丰富交互地应用带来了所有需要的功能.其中一项主要的特性就是Angular带来了对动画的支持. 我们能够在应用的部分内容当中使用动画来表明一些变化正在发生.在我上一篇文章当中,我讲到了在Angular应用中对CSS动画的支持.在这篇文章当中,我们会看到怎样利用JavaScript脚本在AngularJS应用当中生成动画效果. 在Angular当中,CSS和JavaScr

  • Javascript动画效果(3)

    前面我们已经介绍了速度动画.透明度动画.多物体运动和任意值变化,并且我们在Javascript动画效果(二)中介绍到我们封装了一个简单的插件雏形,接下来我们对前面的动画效果进行进一步扩充,尽量将我们的框架做到更实用.在这里我们还需要了解两个运动,一个是链式运动,一个是同时运动.它们间的区别分别是:链式运动是指运动一个接着一个(一个运动完成马上进行下一个运动):而同时运动是指所有的运动同时进行.在这里,我们该如何实现呢? 1.链式运动 前面的效果中,我们已经能对任意值进行相应的变化,我们该如何在一

  • Javascript动画效果(1)

    前面我们介绍了Javascript的回到顶部效果,今天呢,我们对Javascript动画做进一步的研究.在这篇博文中我们只介绍简单的匀速运动.简单的缓冲运动和简单的多物体运动后面我们还会介绍任意值变化的运动.链式运动.同时运动,同时我们还会简单的封装一个运动插件并且还会将Javascript方法和jquery方法进行比较. 1.简单的匀速运动 下面我们介绍一个demo,鼠标移入,动画向右移动(即隐藏部分显示):鼠标离开,动画向左运动(继续隐藏)整个过程都是匀速的.有了前面回到顶部效果作为基础,这

  • Javascript动画效果(4)

    前面我们自己写了一个小小的关于js动画的插件,下面我们来使用之前的框架来完成我们想要的动画效果.我们经常在淘宝网中看到,鼠标经过某一图片时,该图片有从上滚出而又从下滚入的效果,那么那种效果是如何实现的呢? 首先我们我们完成该效果的html和css代码,代码如下: html部分代码: <div id="move"> <a href="#"><i><img src="images/1.jpg"/><

  • javascript动画效果打开/关闭层

    js_打开层关闭层效果_我们 body,span,div,td{font-size:12px;line-height:1.5em;color:#849BCA;} #bodyL{ float:left; width:84px; margin-right:2px; } a.od{ width:80px; height:25px; line-height:25px; text-align:center; font-weight:bold; border: 2px solid #849BCA; disp

  • javascript动画效果类封装代码

    <input id=output3 style="position:absolute;top:300;left:300;"/> <input id=output1 /> <input id=output2 /> <br/> <input id=output4 /> <script> function Animation(target,targetProperty,closure,precision) {   clo

  • JavaScript实现烟花绽放动画效果

    先编写一个烟花绽放的动画效果. 放烟花时,一个烟花可分为两个阶段:(1)烟花上升到空中:(2)烟花炸开成碎片,炸开的碎片慢慢消散. 为此抽象出两个对象类:Firework和Particle.其中,Firework用于表示一个烟花对象,Particle用于表示一个烟花炸开后的各碎片. Firework对象类定义6个属性:表示烟花上升轨迹中各点的坐标(x,y).烟花弧状轨迹的偏转角度angle.上升阶段水平和垂直方向的位移改变量xSpeed和ySpeed.烟花的色彩色相hue. 坐标属性值y的初始值

  • 利用JavaScript在网页实现八数码启发式A*算法动画效果

    最近人工智能课老师布置了一个八数码实验,网上看到很多八数码的启发式A*算法,但是大多数都是利用C或者C++在控制台实现的,于是我用js在网页中做了一个类似的. 首先八数码就是一个九宫格,其中有一个空格,其他八个对应数字1-8, 移动空格,使得最后状态为有序,如下图 启发式算法是指在求解时,利用启发函数将不符合规则的解节点去掉,从而缩小问题的解空间. A*算法是利用评价函数的启发式算法,在本例中,利用当前节点状态与最终节点状态所不同的格子数来评估节点的优劣,将优越节点储存并在之后展开,将劣质节点抛

  • 基于JavaScript实现百叶窗动画效果不只单纯flas可以实现

    看到这种什么百叶窗的动画,以为都是flash实现的,最近突然灵光一闪,想到了用js实现(虽然我不是做前端的,本人做.net).代码虽然实现了,但是比较乱,先上个图: 一个js的动画,以前以为只有flash可以实现 代码主要就是一些数学的计算,然后结合html,css打造出类似flash的效果. 下面贴出主要的部分代码: function all(books){ for(var i=;i<self.rows;i++) { for (var j = ; j < self.columns; j++)

随机推荐