zoukankan      html  css  js  c++  java
  • 构造自己的动画函数:animation,stop功能的实现

    最近做一个广告项目,里面涉及很多动画效果,由于不能使用jquery,所以只能构建自己的动画方法。

    数据结构:

    elem是DOM对象,给它设置一个属性对象,用来记录elem的动画对象,比如'left','opacity'等。该对象的属性又有自己的动画队列,队列的每一项是一个对象,该对象有两个属性start,end,分别用来存储开始的值和动画结束的值,该对象有三个方法,begin,finish是开始结束动画,callbak用来保存该动画结束时需要执行的函数,见下图:

    animation方法:

    分词器,用来解析value表达式,比如:"+=300px"

    function expr(key,value){
            var r=/^(?:(+|-)=)?(-?d+(?:.d+)?)(px|)$/;
            var matches=r.exec(value);
            if(!matches){
                throw new Error("传入参数不能运行动画");
            }else{
                return {
                    "operator":matches[1]?matches[1]:"",
                    "num":matches[2]?matches[2]:"",
                    "unit":matches[3]?matches[3]:""
                };
            }
        }

    调用上边这个方法:

    var matchesEnd=expr(key,value);

    就得到一个分词结果对象:

    {
           "operator":"+",
           "num":300,
           "unit":"px"
    }

    begin方法中,我们需要先获取动画前的样式,代码如下:
    var curValue=_.getAppliedStyle(elem,key);//获取当前样式
                        if((curValue==="auto")&&(revise[key]===0)){////修正top right bottom left width height 默认值为auto的情况
                            value=0;
                        }
                        temp.start=curValue;
                        var matchesStart=expr(key,curValue);//设置动画初始值

    代码:

    动画模块:

    (function(window){
        function expr(key,value){
            var r=/^(?:(+|-)=)?(-?d+(?:.d+)?)(px|)$/;
            var matches=r.exec(value);
            if(!matches){
                throw new Error("传入参数不能运行动画");
            }else{
                return {
                    "operator":matches[1]?matches[1]:"",
                    "num":matches[2]?matches[2]:"",
                    "unit":matches[3]?matches[3]:""
                };
            }
        }
        //method of animation
        //@elem
        //@properties example:{"left":"1000px",top:"200px"} opacity请使用w3c标准:0-1
        //@options  example:{speed:200}
        function animation(elem,properties,options,callback){
            var speed=options.speed||1000;
            var inter=20;
            if(navigator.userAgent.indexOf("MSIE 8.0")>0){
                inter=80;
            }
            if(!elem.ani){
                elem.ani={};
            }
            _.each(properties,function(value,key){
                if(!elem.ani[key]){
                    elem.ani[key]=[];
                }
                var matchesEnd=expr(key,value);
                var temp={};
                if(!matchesEnd.operator){
                    temp.end=value;
                }
                var st;
                if(matchesEnd.num){
                    var i=0;
                    temp.callback=callback;
                    temp.begin=function(){
                        var curValue=_.getAppliedStyle(elem,key);
                        temp.start=curValue;
                        var matchesStart=expr(key,curValue);
                        if(matchesEnd.operator){
                            temp.end=matchesStart.num*1+(matchesEnd.operator==="+"?1*matchesEnd.num:(-1)*matchesEnd.num)+matchesEnd.unit; 
                            matchesEnd=expr(key,temp.end);  
                        }
                        var gap=matchesEnd.num-matchesStart.num;
                        var step=gap/speed*inter;
                        var num=gap/step;
                        st=setInterval(function(){
                            i++;
                            var tempValue=matchesStart.num*1+step*i+matchesEnd.unit;
                            _.setStyle(elem,key,tempValue);
                            if(i>=num){
                                //修正可能的计算错误
                                _.setStyle(elem,key,temp.end);
                                if(callback){
                                    temp.callback.call(temp);
                                }
                                clearInterval(st);
                                elem.ani[key].shift();
                                if(elem.ani[key].length){
                                    elem.ani[key][0].begin();
                                }
                            }   
                        },inter);
                    };
                    temp.finish=function(){
                        if(st){
                            clearInterval(st);
                        }
                    }
    
                    if(elem.ani[key].push(temp)===1){
                        temp.begin();
                    }
                }
            },this);
        }
        function stop(elem,callback){
            for(var key in elem.ani){
                var len=elem.ani[key].length;
                if(len){
                    elem.ani[key][0].finish();
                    if(elem.ani[key][0].callback){
                        elem.ani[key][0].callback.call(this);
                    }
                    _.setStyle(elem,key,elem.ani[key][len-1].end);
                    elem.ani[key].length=0;
                    if(callback){
                        callback();
                    }
                }
            }
        }
        window.AniModule={};
        window.AniModule.animation=animation;
        window.AniModule.stop=stop;
    })(window);

    工具函数:

    (function(){
        var root=this;
        root._={};
        var breaker={};
        var ArrayProto=Array.prototype,
            ObjProto=Object.prototype,
            FuncProto=Function.prototype;
    
        var hasOwnProperty=ObjProto.hasOwnProperty;
    
        //ECMAScript 5 native function
        var nativeForEach=ArrayProto.forEach,
            nativeKeys=Object.keys;
      
    _.isIE=!-[1,];
    _.keys
    =nativeKeys||function(obj){ if(obj!==Object(obj)) throw new TypeError('Invalid object'); var keys=[]; for(var key in obj){ if(hasOwnProperty.call(obj,key)){ keys.push(key); } } return keys; }; _.each=function(obj,iterator,context){ if(obj==null) return; if(nativeForEach&&obj.forEach===nativeForEach){ obj.forEach(iterator,context); }else if(obj.length===+obj.length){ for (var i = 0,length=obj.length; i < length; i++) { if(iterator.call(context,obj[i],i,obj)===breaker) return; } }else{ var keys=_.keys(obj); for(var i=0,length=keys.length;i<length;i++){ if(iterator.call(context,obj[keys[i]],keys[i],obj)===breaker) return; } } }; _.getAppliedStyle=function(elem,styleName){ var style=""; if(styleName== "opacity"&&_.isIE){ style=elem.filters('alpha').opacity/100; }else if(window.getComputedStyle){ style=elem.ownerDocument.defaultView.getComputedStyle(elem,null).getPropertyValue(toHyphens(styleName)); }else if(elem.currentStyle){ style=elem.currentStyle[toCamelCase(styleName)]; } function toHyphens(camelCaseValue){ var result=camelCaseValue.replace(/[A-Z]/g,function(c){ return ("-"+c.charAt(0).toLowerCase()); }); return result; } function toCamelCase(hyphenatedValue){ var result=hyphenatedValue.replace(/-D/g,function(c){ return c.charAt(1).toUpperCase(); }); return result; } return style; }; _.setStyle=function(elem,name,value){ if(name=="opacity"&&_.isIE){ elem.style["filter"]="alpha(opacity="+value*100+")"; }else{ elem["style"][name]!==undefined?elem["style"][name]=value:elem[name] = value; } }; }).call(this);

    调用:animation方法:

    window.AniModule.animation(elem,{"left":"+=300px"},{"speed":1000});

    stop方法:

    window.AniModule.stop(elem);

  • 相关阅读:
    MySQL 基础 查询
    Mysql+keepalived双主
    Kubernetes(二)K8S基础架构
    Kubernetes(一)K8S入门
    Docker (五) 利用Dockerfile创建Nginx镜像
    Docker (四) 使用Dockerfile的方式构建镜像
    Docker (三) 使用commit创建Docker镜像
    Docker (二) Docker网络配置
    Ansible (四) 角色Roles
    Docker (一) Docker入门
  • 原文地址:https://www.cnblogs.com/mufc-go/p/3443807.html
Copyright © 2011-2022 走看看