javascriptアニメーションシリーズ——切替え画像(原生)

15696 ワード

コードに詳しく注解したら、ここでもうクレームしません.
(function(window){

    var m$ = function(){

        function getId(id){

            return document.getElementById(id);

        }

        function getTag(tag){

            return document.getElementsByTagName(tag);

        }

        function extend(des, src){            

            for(var p in src){        //traverse customized configuration by user

                des[p] = src[p];

            }

            return des;

        }

        function each(arr, callback, thisp){        //traverse array

            if(arr.forEach){            //check Array function 

                arr.forEach(callback, thisp);

            }else{

                for(var i=0, len=arr.length; i < len; ++i){

                    callback.call(thisp, arr[i], i, arr);

                }

            }

        }

        function curStyle(ele, style){        //get style, onlyread

            return ele.currentStyle || window.getComputedStyle(ele, null);

        }



        var tween = {        //return sliding distance/per

            quart: {

                easeOut: function(t, b, c, d){        //t:time(the count of slide), b:begin, c:change(the distance in this slide), d:duration(total times/per)

                    return -c * ((t=t/d-1)*t*t*t - 1) + b;

                }

            },

            back: {            //back effects

                easeOut: function(t, b, c, d, s){

                    s == undefined && (s = 1.70158);

                    return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;

                }

            },

            bounce: {            //Rebound effects

                easeOut: function(t, b, c, d){

                    return (t/=d) < (1/2.75) ? c*(7.5625*t*t) + b :

                        (t < (2/2.75)) ? c*(7.5625*(t-=(1.5/2.75))*t + .75) + b : 

                        (t < (2.5/2.75)) ? c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b : c*(7.5625*(t-=(2.25/2.75))*t + .984375) + b;        

                }

            }

        }



        var defaultConfig = {

            trigger: 1,     //the type of trigger

            auto: true,

            tween: tween.quart.easeOut,        //default tween style

            time: 10,        //slide delay

            duration: 50,        //switch time

            pause: 5000,        //auto interval time

            start: function(){},    //switch execute function in the beginning

            end: function(){}        //switch execute function in the end

        };



        function scrollFn(cid, sid, count, config){        //cid: container id, sid: scroller id

            var self = this;

            if(!(self instanceof scrollFn)){

                  return new scrollFn(cid, sid, count, config);    //instantiation

            }

            self.container = getId(cid);

            self.scroller = getId(sid);

            if (!(self.container || self.scroller)) {     //checking to see whether container and scroller exists

                   return;

               } 



            self.config = extend(defaultConfig, config || {});    //replace the part of configs what alter by user

            self.index = 0;

            self.timer = null;        //setTimeout ID

            self.count = count;        //the number of images

            self.step = self.scroller.offsetWidth / count;        //On average, the width of each image

        };



        scrollFn.prototype = {

            constructor: scrollFn,



            transform: function(index){            //transform

                var self = this;

                index == undefined && (index = self.index);  //if the index is undefined, the default for the current index

                index < 0 && (index = self.count - 1) || index >= self.count && (index = 0);

                self.time = 0;

                self.target = -Math.abs(self.step) * (self.index = index);        //slide the target location

                self.begin = parseInt(curStyle(self.scroller)['left']);        //starting position

                self.change = self.target - self.begin;        //slide distance

                self.duration = self.config.duration;    

                self.start();

                self.run();

            },



            run: function(){

                var self = this;

                clearTimeout(self.timer);

                if(self.change && self.time < self.duration){

                    self.moveTo(Math.round(self.config.tween(self.time++, self.begin, self.change, self.duration)));

                    self.timer = setTimeout(function(){self.run()}, self.config.time);

                }else{

                    self.moveTo(self.target);

                    self.config.auto && (self.timer = setTimeout(function(){self.next()}, self.config.pause));    //auto play, call the function: next()

                }

            },



            moveTo: function(i){

                this.scroller.style.left = i + 'px';        //Relative to the containing block

            },



            next: function(){

                this.transform(++this.index);

            }

        };



        return{

            scroll: function(cid, sid, count, config){

                window.onload = function(){

                    var frag = document.createDocumentFragment(),

                        nums = [];

                    for(var i = 0; i < count; i++){        //insert the index of images

                        var li = document.createElement('li');

                        (nums[i] = frag.appendChild(document.createElement('li'))).innerHTML = i + 1;

                    }

                    getId('indexLists').appendChild(frag);        //use fragment, avoid multiple insert



                    var st = scrollFn(cid, sid, count, config);



                    each(nums, function(o, i){        //traverse images and callback   (o: array element, i: the index of array element)

                        o[st.config.trigger == 1 ? 'onclick' : 'onmouseover'] = function(){        //the trigger of mouseover event 

                            o.className = 'on';        //add the className for the target index

                            st.transform(i);

                        }

                        o.onmouseout = function(){

                            o.className = '';        //remove the className

                            st.transform();

                        }

                    });



                    st.start = function(){        //defined start(), handle show the index of selected

                        each(nums, function(o, i){

                            o.className = st.index == i ? 'on' : ''; //add the className for the current index

                        });

                    };

                    st.transform();

                }

            }

        }

    }();



    // Expose jsMolt to the global object

    window.jsMolt = window.m$ = jsMolt = m$;

})(window);



//m$.scroll('c_container' /*    ID*/, 'scroller'/*    ID*/, 5/*      */, {trigger: 0} /*    */);
注:コードオリジナル:Blue Dream