iT邦幫忙

DAY 27
1

jQuery 套件開發之我可不可以跳著說系列 第 23

jQuery套件開發之(二十五),rySpriteMaker完成

因為常常要用css sprite做網頁動畫
所以利用這次的機會寫成套件
還滿開心自己設計的pattern考慮到滿多面向
基本上很合我用
套件原始碼

;(function($, W, D)
{
    String.prototype.format = function()
    {
        var args = arguments ;

        return this.replace(/{(\d+)}/g, function(match, number)
        {
            return typeof (args[number] != 'undefined') ? args[number] : match ;
        }) ;
    } ;
    
    var log = function()
    {
        if (logOn)
        {
            console.log(arguments) ;
        }
    }
    
    var pg      = 'rySpriteMaker' ;    //plugin name
    var pgType  = 'troops' ;    //plugin type
    var logOn   = true ;        //log switch
    var innerSettings =  //settings will never affected by outside.
    {
          indexPrefix: 'ry-'+pg+'-'
        , indexSuffix: '-index-'
        // 'data-'+pg+'-index-' + WIDGET ROLE + '-id-' + number
        , pgAttr: 'ry-'+pg+'-number'
        , actorsClass :
        {
            'widget' : 'ry-'+pg+'-widget'
        }
        , classList:
        {
            'widget' : 'ry-'+pg+'-widget'
        }
        , tpl:
        {
        }
    }    
  
    var defaults =            //settings can be rewrited by outside.
    {
          delay: 0
        , execTime: 1
        , fadeOut: false
        , remove: true
        , zIndex: 1000
        , yStart: '0px'
    } ;
    
    $[pg] = function()          
    {
        $[pg].args = Array.prototype.slice.call(arguments) ;
        $[pg].pgRouter() ;
    } ;
    
    $[pg].version = '0.1' ;
    $[pg].id = 1 ;
    $[pg].settings = {} ;
    $[pg].pgRouter = function()
    {
        if ($[pg].args.length === 2)
        {
            if ($.isFunction( $[pg][ $[pg].args[0] ] ))
            {
                $[pg][ $[pg].args[0] ]( $[pg].args[1] ) ;
            }
            else
            {
                _.log('wrong method: ' + $[pg].args[0]) ;
            }
        }
        else if ($[pg].args.length === 1 && typeof $[pg].args[0] === 'object')
        {   
            $[pg].mkSettings($[pg].args[0]) ;
            $[pg].init() ;
        }
        else if ($[pg].args.length === 1 && ( $.isFunction( $[pg][ $[pg].args[0] ] ) ))
        {
            $[pg][ $[pg].args[0] ]() ;
        }        
        else
        {       
            $[pg].init() ;
        }
    } ;

    $[pg].init = function()
    {
        log('$[pg].init') ;
        $(document)[pg]() ;
    } ;
    
    $[pg].mkSettings = function(arg)
    {
        log('$[pg].mkSettings') ;

        //    運算值                  預設值  設定值  內定值
        $[pg].settings = $.extend({}, defaults, arg, innerSettings) ; 

        log('$[pg].settings:') ;
        log($[pg].settings) ;
    } ;

/*
make a modal to produce widgets
*/
    function Plugin(element)
    {
        log('function Plugin') ;
        
        this.element = element ;
        this.ele$    = $(element) ;
        this.args    = Plugin.args ;
        this.settings = this.mkSettings() ;
        this.id = $[pg].id++ ;      
        log('this.settings:') ; 
        log(this.settings) ; 
        
        this.actors = {} ;
        this.init() ;
    }
/*
super power those widgets have
*/
    Plugin.prototype =
    {
          mkSettings: function()
        {
            log('mkSettings') ; 
            var self = this ;
            var tmpSet = $.extend({}, defaults, $[pg].settings, self.args[0], innerSettings) ;
            tmpSet.width    = Number( tmpSet.width.replace('px', '') ) ;
            tmpSet.height   = Number( tmpSet.height.replace('px', '') ) ;
            tmpSet.x        = Number( tmpSet.x.replace('px', '') ) ;
            tmpSet.y        = Number( tmpSet.y.replace('px', '') ) ;
            tmpSet.wholeW   = Number( tmpSet.wholeW.replace('px', '') ) ;
            tmpSet.yStart   = Number( tmpSet.yStart.replace('px', '') ) ;

            return tmpSet
        }
        , init: function()
        {        
            log('init') ; 
            var self = this ;
            
            self.width = self.settings.width ;
            self.height = self.settings.height ;
            self.x = self.settings.x - (self.width /2)
            self.y = self.settings.y - (self.height /2)
            
            self.createSprite() ;
            self.put() ;
            self.createCss() ;
        }
        , createSprite: function()
        {
            log('createSprite') ;
            var self = this ;
            
            var tmpAttr = self.settings.pgAttr ;
            
            self.actors.widgetIndex = self.settings.indexPrefix + 'widget' + self.settings.indexSuffix + self.id
            self.actors.widget = $('<div />')
                .addClass(self.settings.classList.widget + ' ' + self.actors.widgetIndex)
                .attr(tmpAttr, self.id)
                .css(
                {
                      width: self.width
                    , height: self.height
                    , top: self.y
                    , left: self.x
                    , position: 'absolute'
                    , zIndex: self.settings.zIndex
                }) 
        }
        , put: function()
        {
            log('put') ;
            var self = this ;
            
            self.actors.widget
                .appendTo('body') ;
        }
        , createCss: function()
        {
            log('put') ;
            var self = this ;
            
            if (self.settings.execTime === 0)
            {
                var isInfinite = 'infinite' ;
                var setIterationCount = '' ;
            }
            else
            {
                var isInfinite = '' ;
                var setIterationCount = '-webkit-animation-iteration-count:' + self.settings.execTime ;
            }
            
            var widgetCss = '.'+self.actors.widgetIndex+' {'+
                            'background-image: url("'+ self.settings.url +'");'+
                            '-webkit-animation: rySpriteMaker_tmpCssFn_'+self.id+' '+self.settings.duration+'s steps('+self.settings.steps+') '+ isInfinite +' ;'+
                            '-webkit-animation-delay:'+ self.settings.delay +'s;'+
                            setIterationCount +
                            '}' ;
            var animateFn = '@-webkit-keyframes rySpriteMaker_tmpCssFn_'+self.id+' {'+
                            'from { background-position:0 -'+ self.settings.yStart +'px ; }' +
                            'to { background-position: -'+self.settings.wholeW+'px -'+ self.settings.yStart +'px;}'+
                            '}' ;
                            
            $('<style />')
                .text(widgetCss + animateFn)
                .appendTo('body') ;
                
            if (self.settings.remove && self.settings.execTime !== 0)
            {
                setTimeout(function()
                {
                    self.actors.widget.remove() ;
                }, 1000 * (self.settings.execTime * self.settings.duration + self.settings.delay) - 50) ;
            }
        }

    }
    
    $.fn[pg] = function() 
    {   
        //處裡套件全域設定
        Plugin.args = Array.prototype.slice.call(arguments) ;
        return this.each(function() {
            if (pgType === 'troops')
            {
                $.data(this, pg+'Num', $[pg].id);
                
                var tmpAry = ( $.isArray($.data(this, 'plugin_' + pg)) )? $.data(this, 'plugin_' + pg) : [] ;
                
                tmpAry[$[pg].id] = new Plugin(this) ;
                
                $.data(this, 'plugin_' + pg, tmpAry) ;
            }
            else
            {
                if (!$.data(this, 'plugin_' + pg)) 
                {
                    $.data(this, 'plugin_' + pg, new Plugin(this));
                }
                else if ($.isFunction(Plugin.prototype[ Plugin.args[0] ]))
                {
                    $.data(this, 'plugin_' + pg)[ Plugin.args[0] ]();  //吃參數
                }
                else
                {
                    console.log('wrong way to use this method:' + Plugin.args[0]) ;
                }            
            }
            log('$(this).data():') ;
            log($(this).data()) ;
        });
    }  
        
    $(document)
        .on('click', function(e)
        {
            console.log('bind event test') ;
        }) ;
})( jQuery, window, document ) ;

使用方式

    $.rySpriteMaker(
    {
          url : 'css/images/spr3.png'
        , width: '120px'
        , height: '150px'
        , x: '100px'
        , y: '100px'
        , steps: 8
        , duration: 0.7
        , wholeW: '960px'
        , delay: 0//default: 0
        , execTime: 3 //default: 1, 0 means infinite
        , remove: false //default: true
        , zIndex: 2000 //default: 1000
        //, yStart: '0px'  //default: 1
    }) ;
    
    $.rySpriteMaker(
    {
          url : 'css/images/spr3.png'
        , width: '120px'
        , height: '150px'
        , x: '200px'
        , y: '100px'
        , steps: 6
        , duration: 0.5
        , wholeW: '720px'
        , delay: 0//default: 0
        , execTime: 4 //default: 1, 0 means infinite
        , remove: false //default: true
        , zIndex: 2000 //default: 1000
        , yStart: '150px'  //default: 1
    }) ;    
    
    $.rySpriteMaker(
    {
          url : 'css/images/spr3.png'
        , width: '120px'
        , height: '150px'
        , x: '100px'
        , y: '200px'
        , steps: 12
        , duration: 1.2
        , wholeW: '1200px'
        , delay: 0//default: 0
        , execTime: 5 //default: 1, 0 means infinite
        , remove: false //default: true
        , zIndex: 2000 //default: 1000
        , yStart: '300px'  //default: 1
    }) ;    
    
    $.rySpriteMaker(
    {
          url : 'css/images/spr3.png'
        , width: '120px'
        , height: '150px'
        , x: '200px'
        , y: '200px'
        , steps: 9
        , duration: 1
        , wholeW: '1080px'
        , delay: 0//default: 0
        , execTime: 6 //default: 1, 0 means infinite
        , remove: false //default: true
        , zIndex: 2000 //default: 1000
        , yStart: '450px'  //default: 1
    }) ; 

demo
http://ry.url.tw/wp/doc/c/c2.htm


上一篇
jQuery套件開發之(二十四),rySpriteMaker
下一篇
jQuery套件開發之(二十六),canvas練習
系列文
jQuery 套件開發之我可不可以跳著說26

尚未有邦友留言

立即登入留言