zoukankan      html  css  js  c++  java
  • 【分享】2.5KB打造jquery的animate。(自定义动画)

    第一篇文章是前几天写的。当时也不知道是不是发神经了。就模仿jquery的animate写了一个简单的动画实现方法。
    后来发现还不错。不如继续写下去。这个版本基本上跟jquery的animate一样了。我是说效果基本上一样了。(效率还没测试过。);
    如果有专业测试人员 帮我测试下。

    第一篇文章是前几天写的。当时也不知道是不是发神经了。就模仿jquery的animate写了一个简单的动画实现方法。

    后来发现还不错。不如继续写下去。

    这个版本基本上跟jquery的animate一样了。

    我是说效果基本上一样了。(效率还没测试过。);

    如果有专业测试人员 帮我测试下。

    演示

    id:cc



    1:功能说明

      兼容主流浏览器。

         1:支持回调函数;

       2:支持级联动画调用;

         3:支持delay动画队列延迟;

       4:支持stop停止动画;

         5:支持opacity透明度变化;

         6:支持+= -= *= /=操作;

         7:支持单位操作(px, %);

    2:使用说明

    jelle(A).animate(B, C, D);

    A:需要执行动画的dom元素ID;

    B:动画的主要参数传递{key,val,key2,val2};比如{'100px',height:'+=100px',opacity:0.5},

        opacity--透明度变化  支持+=  -=  *= /=操作。

    C:动画执行用时,以毫秒为单位;[可选 默认500毫秒];

    D:回调函数;[可选]

    3:方法说明

       1:animate()方法

    jelle('cc').animate({'100px'},300,function(){alert('完成')});
    // 是 cc 的宽度在300毫秒的时间变化到100px 动画结束 弹出 ‘完成’

       2:stop()方法

    jelle('cc').stop();
    //停止正在 cc 对象上播放的动画。

      3:delay()方法

    jelle('cc').delay(1000).animate({'100px'});
    //cc 的宽度发生变化 将被延迟1秒执行。

    我会一直把他完善下去。


    点击下载源码和压缩后的JS

    压缩过的源码
    var jelle=function(h){var a=document.getElementById(h),o=0,e={},l=10,k=function(b,c,g,d){return-g*(b/=d)*(b-2)+c},n=function(b,c){var g,d=/^([+-\\*\/]=)([-]?[\d.]+)/;if(d.test(b)){d=b.match(d);d[2]=parseFloat(d[2]);switch(d[1]){case "+=":g=d[2];break;case "-=":g=-d[2];break;case "*=":g=c*d[2]-c;break;case "/=":g=c/d[2]-c;break}return g}return parseFloat(b)-c};a.animate=a.animate||[];jelle[h]={};jelle[h].stop=true;e.entrance=function(b,c,g){setTimeout(function(){b(c[0],c[1],c[2])},g||0)};e.stop=function(){jelle[h].stop=
    false;a.animate.length=0;document.getElementById(h).animate.length=0;return e};e.queue=function(){if(a.animate&&++o==a.animate[0].length){o=0;a.animate[0].callback&&a.animate[0].callback.apply(a);if(a.animate.length>1){a.animate[0].callback=a.animate[1].callback;a.animate=document.getElementById(h).animate||[];a.animate.shift();document.getElementById(h).animate=a.animate;for(var b=a.animate[0],c=0;c<b.length;c++)b[c][0]==="opacity"?e.entrance(e.alpha,[b[c][1],b[c][2]],l):e.entrance(e.execution,[b[c][0],
    b[c][
    1],b[c][2]],l)}else{a.animate.length=0;document.getElementById(h).animate.length=0}}};e.delay=function(b){l=b;return e};e.execution=function(b,c,g){var d=(new Date).getTime(),f=g||500,j=parseFloat(a.style[b])||0,i=n(c,j),p=c.match(/\d+(.+)/)[1];(function(){var m=(new Date).getTime()-d;if(m>f){m=f;a.style[b]=parseInt(k(m,j,i,f))+p;e.queue();return e}a.style[b]=parseInt(k(m,j,i,f))+p;jelle[h].stop&&setTimeout(arguments.callee,10)})()};e.animate=function(b,c,g){var d=a.animate.length;a.animate[d]=
    [];a.animate[d].callback
    =g;for(var f in b){a.animate[d].push([f,b[f],c]);if(d==0)f=="opacity"?e.entrance(e.alpha,[b[f],c],l):e.entrance(e.execution,[f,b[f],c],l)}document.getElementById(h).animate=a.animate;return e};e.alpha=function(b,c){var g=(new Date).getTime(),d=c||500,f,j;if(document.defaultView){f=document.defaultView.getComputedStyle(a,null).opacity||1;j=n(b,f)*100;(function(){var i=(new Date).getTime()-g;if(i>d){i=d;a.style.opacity=k(i,100*f,j,d)/100;e.queue();return e}a.style.opacity=k(i,
    100*f,j,d)/100;jelle[h].stop&&setTimeout(arguments.callee,10)})()}else{f=a.currentStyle.filter?a.currentStyle.filter.match(/^alpha\(opacity=([\d\.]+)\)$/)[1]/100:1;j=n(b,f)*100;(function(){var i=(new Date).getTime()-g;if(i>d){i=d;a.style.filter="alpha(opacity="+k(i,100*f,j,d)+")";e.queue();return e}a.style.filter="alpha(opacity="+k(i,100*f,j,d)+")";jelle[h].stop&&setTimeout(arguments.callee,10)})()}};return e};

    代码
    var jelle = function(id){
    var $ = function(id){ return document.getElementById(id); },
    elem
    = $(id),//对象
    f = 0, _this = {}, lazy = 10, lazyque = 10,// f动画计数器 lazy动画延迟 lazyque队列延迟
    // 算子你可以改变他来让你的动画不一样
    tween = function(t, b, c, d){ return - c * (t /= d) * (t - 2) + b},
    // adv 用于+= -= *= /=操作
    adv = function(val, b){
    var va, re= /^([+-\\*\/]=)([-]?[\d.]+)/ ;
    if (re.test(val)){
    var reg = val.match(re);
    reg[
    2] = parseFloat(reg[2]);
    switch ( reg[1] ){
    case '+=':
    va
    = reg[2];
    break;
    case '-=':
    va
    = -reg[2];
    break;
    case '*=':
    va
    = b*reg[2] - b;
    break;
    case '/=':
    va
    = b/reg[2] - b;
    break;
    }
    return va;
    }
    return parseFloat(val) - b;
    }
    // elem.animate 读取用于当前dom元素上的动画队列
    elem.animate = elem.animate || [];

    //stop 功能要使用的
    jelle[id]= {};
    jelle[id][
    'stop'] = true;
    //alert(jelle[id]['stop'])
    // 统一队列入口 用于方便设置延迟,与停止
    _this.entrance = function(fn, ags, lazytime){
    //fn 调用函数 ags 参数 lazytime 延迟时间
    setTimeout(function(){
    fn(ags[
    0], ags[1], ags[2]);
    }, (lazytime
    || 0));

    }

    // 停止动画 此方法还不能用
    _this.stop = function(){
    jelle[id][
    'stop'] = false;
    elem.animate.length
    =0;
    $(id).animate.length
    =0;
    return _this;
    }

    // 队列操作
    _this.queue = function(){

    if (elem.animate && ++f == elem.animate[0].length){
    f
    = 0;// 清空计数器
    elem.animate[0].callback ? elem.animate[0].callback.apply(elem) : false;

    // 判断是否有动画在等待执行
    if (elem.animate.length > 1){
    elem.animate[
    0].callback = elem.animate[1].callback;
    elem.animate
    = $(id).animate || [];// 从dom对象上获取最新动画队列
    elem.animate.shift();// 清除刚执行完的动画队列
    $(id).animate = elem.animate;// 把新的队列更新到dom
    var ea = elem.animate[0];

    // 循环播放队列动画
    for(var i = 0; i < ea.length; i++){

    ea[i][
    0] === 'opacity' ? _this.entrance(_this.alpha, [ea[i][1], ea[i][2]], lazyque):
    _this.entrance(_this.execution, [ea[i][
    0], ea[i][1], ea[i][2]], lazyque);

    }
    }
    else{
    elem.animate.length
    = 0; // 队列清楚
    $(id).animate.length = 0; // 队列清楚
    }

    }
    }

    //设置lazy方法,以后的队列动画延迟时间
    _this.delay = function(val){
    lazyque
    = val;
    return _this;
    }
    //动画变化
    _this.execution = function(key, val, t){
    //alert(val)
    var s = (new Date()).getTime(), d=t || 500 ,
    b
    = parseFloat(elem.style[key]) || 0 ,
    c
    = adv(val, b) ,// adv用于设置高级操作比如 += -= 等等
    un = val.match(/\d+(.+)/)[1];// 单位
    (function(){
    var t = (new Date()).getTime() - s;
    if (t > d){
    t
    = d;
    elem.style[key]
    = parseInt(tween(t, b, c, d)) + un;
    _this.queue();
    // 操作队列
    return _this;
    }
    elem.style[key]
    = parseInt(tween(t, b, c, d)) + un;
    jelle[id][
    'stop'] && setTimeout(arguments.callee, lazy);
    // _this.entrance(arguments.callee,[1,1,1],lazy);
    // arguments.callee 匿名函数递归调用
    })();
    }
    // 入口
    _this.animate = function(sty, t, fn){
    // sty,t,fn 分别为 变化的参数key,val形式,动画用时,回调函数
    var len = elem.animate.length;// len查看动画队列长度
    elem.animate[len] = [];
    elem.animate[len].callback
    = fn;

    //多key 循环设置变化
    for(var i in sty){

    elem.animate[len].push([i, sty[i], t]);
    if(len == 0){
    i
    == 'opacity' ? _this.entrance(_this.alpha, [sty[i], t], lazyque) :
    _this.entrance(_this.execution, [i, sty[i], t], lazyque);
    }
    }
    $(id).animate
    = elem.animate;//把新的动画队列添加到dom元素上
    return _this;
    }
    // 透明度变化的代码
    _this.alpha = function(val, t){
    var s = (new Date()).getTime(),
    d
    = t || 500, b, c;
    if( document.defaultView ){
    b
    = document.defaultView.getComputedStyle(elem,null)['opacity'] || 1,
    c
    = adv(val,b) * 100;
    (
    function(){
    var t = (new Date()).getTime() - s;
    if(t > d){
    t
    = d;
    elem.style[
    'opacity'] = tween(t, (100 * b), c, d) / 100;
    _this.queue();
    // 队列控制
    return _this;
    }
    elem.style[
    'opacity'] = tween(t, (100 * b), c, d) / 100;
    jelle[id][
    'stop'] && setTimeout(arguments.callee, lazy);
    })()
    }
    else{
    b
    = elem.currentStyle['filter'] ?
    (elem.currentStyle[
    'filter'].match(/^alpha\(opacity=([\d\.]+)\)$/))[1]/100 : 1;
    c = adv(val, b) * 100;
    (
    function(){
    var t = (new Date()).getTime() - s;
    if (t > d){
    t
    = d;
    elem.style[
    'filter']='alpha(opacity='+ tween(t, (100 * b), c, d) +')';
    _this.queue();
    // 队列控制
    return _this;
    }
    elem.style[
    'filter'] = 'alpha(opacity='+ tween(t, (100*b) , c, d) +')';
    jelle[id][
    'stop'] && setTimeout(arguments.callee, lazy);
    })()
    }
    }
    return _this;
    }

    程序可能每天都在修改。如果想要最新的ainimate 可以email联系我。

    上面的代码已经不是最新的了。

    这两天又修正了几个错误的地方。

    本文来自博客园 jelle 博客 http://www.cnblogs.com/idche/

    转载请注明。

  • 相关阅读:
    dataframe字段过长被截断
    sublime text 3安装Anaconda插件之后写python出现白框
    在tkinter中使用matplotlib
    RemoteDisconnected: Remote end closed connection without response
    object of type 'Response' has no len()
    matploylib之热力图
    pycharm格式化python代码快捷键Ctrl+Alt+L失效
    Windows下Redis集群配置
    七牛云--对象存储
    Spring发送邮件
  • 原文地址:https://www.cnblogs.com/idche/p/1759605.html
Copyright © 2011-2022 走看看