zoukankan      html  css  js  c++  java
  • jq动画分析

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    </head>
    
    <style>
    
    
    #box{
    opacity:1;
    position: relative;
    top:100px;
    left: 0px;
    300px;
    height:300px;
    border:1px #ccc solid;
      
      }
    #book{
    opacity:1;
    position:absolute;
    top:100px;
    left: 100px;
    100px;
    height:100px;
    background: red; 
      }
      
      #book1{
    opacity:1;
    position:absolute;
    top:220px;
    left: 0px;
    100px;
    height:100px;
     background: red; 
      }
    .line{
     
    position:absolute;
    top:0px;
    left: 200px;
    1px;
    height:500px;
     background:#000;
        
        }
    </style>
    <!--<script src="../jquery-2.2.3.js"></script>-->
     <body>
    <button id="one">jQuery动画的模拟实现:放大</button> 
    <button id="two">jQuery动画的模拟实现:缩小</button>
     <div id="box"> 
      <div id="book" ></div>
     </div> 
    <!-- <div id="book1" ></div>-->
    <!-- <div class="line"></div>-->
    <script  >
      /*在ie中 consloe.log 如果不在控制台的时候会报错, 调试的时候 按f12 控制台 即可*/
    
    var book = document.getElementById('book');
    var book1 = document.getElementById('book1');
    var one = document.getElementById('one');
    var two = document.getElementById('two');
    
    /*var $book = $('#book');
    var i = 10
    while(i){
        $book.append("<li>11</li>")
        i--;
    }*/
    
    
    ////////////
    //创建动画缓动对象 //
    ////////////
     //生成属性对应的动画算法对象
        // tweens保存每一个属性对应的缓动控制对象
        //properties[k] 值
        // k 是建
        //animation 动画对象
        // 参数为:animation.tweens.push( new Tween(properties[k], k, animation) )
        //Tween 构造函数
        // this.elem 就是用户传进来的dom节点
        //this.prop    = prop; 对象的属性
        //this.easing  = "swing"; //动画缓动算法
        //this.end动画最终值
        //单位 this.unit    = "px"
        //Tween 函数是初始化构造函数
        
    function Tween(value, prop, animation) {
        //初始化
        this.elem    = animation.elem;
        this.prop    = prop;
        this.easing  = "swing"; //动画缓动算法
        this.options = animation.options;
        //获取初始值,就是获取动画样式的值, this.get();  
        this.start   = this.now = this.get();
        //动画最终值,就是用户输入的值
        this.end     = value;
        //单位
        this.unit    = "px"
    }
    //获取动画样式
    function getStyles(elem, attr) {
        //return elem.ownerDocument.defaultView.getComputedStyle(elem, null);
        
        if(elem.currentStyle) {
                 // ie   //这样兼容性强
                //console.log('attr='+attr+'||elem.currentStyle[attr]='+elem.currentStyle[attr])  
                 if(elem.currentStyle[attr]=='auto'){
                       elem.style[attr] = '0px';
                     }
                  return elem.currentStyle[attr];
            } else { 
                //ff w3c.
              
                 return getComputedStyle(elem,false)[attr];
             } 
    };
    
    //动画算法
    function swing(p) {
        //p 是动画时间比 0 ~ 1
        //Math.cos(x)    x 的余弦值。返回的是 1.0 到 -1.0 之间的数;
        //(p * Math.PI) 是 0到3.14
        //(p * Math.PI)/2  是0到1.57
        //所以   Math.cos(p * Math.PI) / 2   值: 0.5 ~ -05
        //tmpe 值越大跑的越快 
        var tmpe = 0.5 - Math.cos(p * Math.PI) / 2; 
        // tmpe = Math.sin(p*Math.PI/2)
        // console.log('p * Math.PI='+Math.sin(p * Math.PI))
         //console.log('Math.sin(p * Math.PI)='+ Math.sin(p*Math.PI/2));
        // console.log('Math.cos(p * Math.PI) / 2='+ Math.cos(p * Math.PI) / 2)
         // console.log('tmpe='+tmpe)
        return tmpe
    }
    
    
    Tween.prototype = {
        //获取元素的当前属性
        get: function() {
            var computed = getStyles(this.elem, this.prop);
            //var ret = computed.getPropertyValue(this.prop) || computed[this.prop];
            //var ret = computed[this.prop];
            //获取样式的值
            //return parseFloat(ret);
            return parseFloat(computed);
        },
        //运行动画
        run:function(percent){
            //percent 动画时间比 0-1
            var eased;
            //根据缓动算法改变percent
            this.pos = eased = swing(percent);
            //获取具体的改变坐标值 this.now缓冲值
              
            //this.now  (等于结束动画位置 - 开始动画的位置)* 时间戳比例,时间戳比例是从0 ~ 1  this.start 是起始的位置
            this.now = (this.end - this.start) * eased + this.start;
            //console.log('this.now='+this.now)
             
            //console.log('this.prop='+this.prop+'||this.start='+this.start)
            //最终改变坐标
            //console.log('this.prop='+this.prop+'||this.now='+this.now)
            
            this.elem.style[this.prop] = this.now + "px";
            return this;
        }
    }
    
    
    ////////
    //动画类 //
    ////////
    //动画对象  elem
     //properties 动画属性
     //options 动画时间  
    function Animation(elem, properties, options){
          //检查动画是否在执行     
        if (Animation.timerId !=undefined && Animation.timerId) {
                return false;
            }
        //动画对象
        //animation.elem 动画对象
        //animation.props 动画属性
        //options.options 动画时间
        //Animation.fxNow || createFxNow() 开始动画的时间
        //tweens          : [] //存放每个属性的缓动对象,用于动画
        var animation = {
            elem            : elem,
            props           : properties,
            originalOptions : options,
            options         : options,
            startTime       : null,//动画开始时间
            tweens          : [] //存放每个属性的缓动对象,用于动画
        }
    
        //生成属性对应的动画算法对象
        // tweens保存每一个属性对应的缓动控制对象
        //properties[k] 值
        // k 是建
        //animation 动画对象
        for (var k in properties) {
         
            // tweens保存每一个属性对应的缓动控制对象
            animation.tweens.push( new Tween(properties[k], k, animation) )
        }
    
        //动画状态
        //var stopped;
        //把 animation.startTime=Animation.fxNow || createFxNow(); 放在这里 为了避免 for (var k in properties) for循环的时候如果属性多的时候会出现时间误差,虽然不是很大,但是如果属性很多的话就显得很明显
        animation.startTime=Animation.fxNow || createFxNow();
        //动画的定时器调用包装器  动画循环函数 tick 每13毫秒执行一次
        var tick = function() {
            // console.log(1)
            //如果 stopped 为真则 停止函数
            //if (stopped) {
            //    return false;
            //}
            
            //动画时间算法  每次更新动画的时间戳
            var currentTime = Animation.fxNow || createFxNow();
                //运动时间递减  
                remaining = Math.max(0, animation.startTime + animation.options.duration - currentTime),
                //时间比
                temp = remaining / animation.options.duration || 0,
                //取反时间比
                percent = 1 - temp;
    
            var index = 0,
                length = animation.tweens.length;
    
            //执行动画改变
            for (; index < length; index++) {
                //percent改变值
                //animation.tweens[index] 动画的对 象percent 动画时间比 0-1
                // run 就是一个动画执行多少个动画属性
                animation.tweens[index].run(percent);
            }
    
            //是否继续,还是停止动画  percent <= 1 表示动画已经到达位置了
            if (percent <= 1 && length) {
                 
                return remaining;
                
            } else {
                //停止 动画
                 
                return false;
            }
    
        }
        tick.elem = elem;
        tick.anim = animation;
       //只是调用一次而已
       //console.log(3333)
        Animation.fx.timer(tick);
    }    
    
    //创建 获取时间戳 函数
    function createFxNow() {
        setTimeout(function() {
            //给 Animation.fxNow = undefined; 一个空的对象
            Animation.fxNow = undefined;
        });
        //Date.now() 时间戳
        return (Animation.fxNow = Date.now());
    }
    
    
     
    
    Animation.fx = {
        //开始动画队列  这个函数也是执行一次而已
        timer: function(timer) {
            
               //这里是把函数放到一个数组里面?有何用处
            Animation.timer=timer;
             
            if (timer()) {  //timer() 只是调用一个而已,就是说有这个动画时候就执行函数 返回一个false 或者是 remaining;
                //开始执行动画 走这里
                Animation.fx.start();
            }  
        },
        //开始循环 这个函数也是执行一次而已
        start: function() {
            if (!Animation.timerId) {
                 
                Animation.timerId = setInterval(Animation.fx.tick, 13);
            }
        },
        //停止循环 停止定时器
        stop:function(){
            clearInterval(Animation.timerId);
            Animation.timerId = null;
            
        },
        //循环的的检测  重点是这里
        tick: function() {
             var timer,
                i = 0;
             //每次更新时间戳
             Animation.fxNow = Date.now();
             //console.log(1)
             //如果所有的动画都执行完了就停止这个定时器
            if (!Animation.timer()) {
                //console.log('Animation.timer()')
                //console.log(!Animation.timer())
                Animation.fx.stop();
             }
            //问题出在这里,因为当执行完只有 Animation.fxNow 时间戳变量值还在,所以就产生了bug
             Animation.fxNow = undefined;
        }
    }
    
    
    
    
    
     one.onclick=function(){
         
        Animation(book, {
             'width': '300',
             'height':'300',
             'marginLeft':'-100',
             'marginTop':'-100'
        }, {
            duration: 1000
        })
        
        
        
         
        
    } 
    
    two.onclick=function() {
         
        Animation(book, {
             '100',
            height:'100',
            marginLeft:'0',
            marginTop:'0'
         }, {
            duration: 1000
        })
    } 
    
    
    
    
    
    
    
    
    
    
    
    
    
     
    </script>
    </body>
    </html>
  • 相关阅读:
    C++编译器详解(二)常见precompiling 指令介绍
    C++编译器详解(一)
    Music
    jQuery语法
    Freedom DownTime
    A
    Map类
    伤不起:File.toPath() & Paths.get()
    在不同浏览器中空格显示的效果不一致的问题(主要是宽度不一致)
    关于xmlhttp会使用ie的缓存的问题及解决
  • 原文地址:https://www.cnblogs.com/hao123456/p/5525967.html
Copyright © 2011-2022 走看看