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>

  • 相关阅读:
    个人总结05
    微软拼音的用户体验
    个人总结04
    典型用户和用户场景模式
    个人总结03
    个人总结02
    构建之法阅读笔记06
    个人总结01
    学习进度条——第七周
    WebApi学习总结系列第五篇(消息处理管道)
  • 原文地址:https://www.cnblogs.com/hao123456/p/5525933.html
Copyright © 2011-2022 走看看