CSSTransitionに薄皮

今のところwebkit限定。prefixを-mozに振り分ければfirefoxでも動くかもね。

(function(){
    var preventDefault = function(e){
        e.preventDefault();
    };
    this.__defineSetter__('enableTouchSlide',function(enableTouchSlide){
        this.__enableTouchSlide = enableTouchSlide ? true : false;
        if( this.__enableTouchSlide ){
            this.removeEventListener('touchmove',preventDefault);
        }else{
            this.addEventListener('touchmove',preventDefault);
        }
    });
    this.__defineGetter__('enableTouchSlide',function(){
        return (this.__enableTouchSlide !== false );
    });
}).apply(HTMLElement.prototype);

(function(){
    var objectKeys = (Object.keys) ? Object.keys :function(obj){
        var ret = [];
        for( var p in obj )
            if( obj.hasOwnProperty( p ) )
                ret.push(p);
        return ret;
    };
    var camelize = function(str){
        return str.replace(/-+(.)?/g,function(match,chr){
            return chr ? chr.toUpperCase():'';
        })
    };
    var getPrefixedObject = function(prefix,obj){
        var ret = {};
        objectKeys(obj).forEach(function(p){
            ret[prefix+p] = obj[p];
        });
        return ret;
    };
    var prefixed = function(prop){
        if( /^transition/.test(prop) )
            return 'webkit-' + prop;
        if( /^animation/.test(prop) )
            return 'webkit-' + prop;
        if( /^transform/.test(prop) )
            return 'webkit-' + prop;
        return prop;
    };
    this.setStyle = function(styleObject){
        var _self = this;
        objectKeys(styleObject).forEach(function(p){
            _self.style[camelize(prefixed(p))] = styleObject[p].toString();
        });
        return this;
    };
    this.getStyle = function(name){
        return this.style[camelize(prefixed(name))];
    };
}).apply(HTMLElement.prototype);

var $ = function(a){return document.getElementById(a)};



CSSRule.Transform = (function(){
    var _Transform = function(){
        this.expression = '';
    };
    (function(){
        this.scale = function(x,y){
            this.expression += 'scale('+[x||1,y||1].join(',')+') ';
            return this;
        };
        this.rotate = function(deg){
            this.rotate += 'rotate(' + deg + 'deg) ';
            return this;
        };
        this.translate = function(x,y){
            this.expression += 'translate(' + 
                [x ||'0',y||'0'].map(function(ex){return ex + 'px';}).join(',') +
            ') ';
            return this;
        };
        this.skew   = function(x,y){
            this.expression += 'skew(' + 
                [x ||'0',y||'0'].map(function(ex){return ex + 'deg';}).join(',') +
            ') ';
            return this;
        };
        this.toString = function(){
            return this.expression;
        };
    }).apply(_Transform.prototype);

    return {
        scale : function(){
            var instance = new _Transform;
            _Transform.prototype.scale.apply( instance ,arguments );
            return instance;
        },
        rotate : function(){
            var instance = new _Transform;
            _Transform.prototype.rotate.apply( instance ,arguments );
            return instance;
        },
        translate : function(){
            var instance = new _Transform;
            _Transform.prototype.translate.apply( instance ,arguments );
            return instance;
        },
        skew : function(){
            var instance = new _Transform;
            _Transform.prototype.skew.apply( instance ,arguments );
            return instance;
        }
    };
})();
Element.Transition = (function(){
    var parseTime = function(str){
        return parseFloat(str||"0") * (( /ms$/.test(str) ) ? 1: 1000);
    };

    var _TransitionElement = function(element,transitions){
        var options   = transitions || {};
        this.element  = element;
        this._toStyle = {};
        this._afterStyle = {};
        this.element.setStyle({
            'transition-duration' : ( options.duration || 600 ) + 'ms',
            'transition-property' : ( options.property || 'all'),
            'transition-timing-function' : 
                ( typeof options['timing-function'] === 'string' ) ? options['timing-function'] :
                ( typeof options['timing-function'] === 'undefined') ? 'ease' :
                'cubic-bezier(' + options['timing-function'].join(',') + ')'
        });
        var _self = this;
        setTimeout(function(){ 
            _self.element.setStyle(_self._toStyle || {});
        },10);
        var durationTime = parseTime(_self.element.getStyle('transition-duration')) + 
            parseTime(_self.element.getStyle('transition-delay'));

        setTimeout(function(){
            _self
                .element
                .setStyle( { 'transition-duration' : '0s' ,'transition-property' : 'none'})
                .setStyle( _self._afterStyle || {} );
            ( _self._callback || function(){}).apply(_self);
        }, durationTime );
    };
    (function(){
        this.from = function(styleObject){
            this.element
                .setStyle(styleObject||{})
            return this;
        };
        this.to = function(styleObject){
            this._toStyle = styleObject;
            return this;
        };
        this.after = function(styleObject){
            this._afterStyle = styleObject;
            return this;
        };
        this.callback = function(callback){
            this._callback = callback;
        };
    }).apply(_TransitionElement.prototype);
    return function(element,extraOptions){ return new _TransitionElement(element,extraOptions);}

})();

HTMLElement.prototype.transition = function(options){
    return Element.Transition( this,options );
};