Skip to content

Instantly share code, notes, and snippets.

@cpojer
Created March 29, 2011 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cpojer/892952 to your computer and use it in GitHub Desktop.
Save cpojer/892952 to your computer and use it in GitHub Desktop.
Builds on my Element.Style
(function(){
var hasTransitionSupport = (document.html.style[Element.getStyleProperty('transition')] != null),
prefix = Element.getVendorPrefix('transition'),
key = prefix.replace(/-/g, ''),
Key = key.capitalize(),
Transition = 'Transition',
durationProperty = Key + Transition + 'Duration',
transitionProperty = Key + Transition,
transition = key ? key + Transition : 'transition',
animation = key ? key + 'Animation' : 'animation',
start = 'Start',
end = 'End',
iteration = 'Iteration',
events = Element.NativeEvents,
setStyleProperty = function(event){
event.styleProperty = event.event.propertyName.replace(prefix, '');
return true;
};
if (key == 'moz'){
animation = 'animation';
transition = 'transition';
start = start.toLowerCase();
end = end.toLowerCase();
iteration = iteration.toLowerCase();
}
events[transition + start] = 2;
events[transition + end] = 2;
events[animation + start] = 2;
events[animation + end] = 2;
events[animation + iteration] = 2;
if (hasTransitionSupport){
Element.defineCustomEvent('animationStart', {
base: animation + start
}).defineCustomEvent('animationComplete', {
base: animation + end
}).defineCustomEvent('animationIteration', {
base: animation + iteration
}).defineCustomEvent('transitionStart', {
base: transition + start,
condition: setStyleProperty
}).defineCustomEvent('transitionComplete', {
base: transition + end,
condition: setStyleProperty
}).defineCustomEvent('transformComplete', {
base: transition + end,
condition: function(event){
setStyleProperty(event);
return (event.styleProperty == 'transform');
}
});
} else {
// TODO fix this
var createEvent = function(){
var event = new Event({
type: 'transitionStart',
propertyName: 'transform'
});
setStyleProperty(event);
return event;
};
Element.defineCustomEvent('transitionComplete', {
base: transition + end,
onAdd: function(fn){
fn.delay(50, this, createEvent());
return false;
}
}).defineCustomEvent('transitionStart', {
base: transition + start,
onAdd: function(fn){
fn.delay(1, this, createEvent());
return false;
}
}).defineCustomEvent('transformComplete', {
base: transition + end,
onAdd: function(fn){
fn.delay(50, this, createEvent());
return false;
},
condition: function(event){
return true;
}
});
}
var splitter = /\s*,\s*/;
var normalizeTime = function(string){
return string.replace(/([0-9.]+)s/g, function(all, value){
return value.split('.').join('').pad(4, 0) + 'ms';
});
};
var toInt = function(value){
return parseInt(value, 10);
};
Element.defineStyleSetter(Key + Transition + 'Property', function(value){
value = value.split(splitter).map(Element.getStyleProperty).join(', ');
this.style[Key + Transition + 'Property'] = value || '';
}).defineStyleGetter(Key + Transition + 'Duration', function(){
return normalizeTime(this.style[Key + 'TransitionDuration']);
}).defineStyleGetter(Key + Transition + 'Delay', function(){
return normalizeTime(this.style[Key + 'TransitionDelay']);
}).implement({
getTransitionProperties: function(){
return this.getStyle('transitionProperty').split(splitter);
},
getTransitionDurations: function(){
return this.getStyle('transitionDuration').split(splitter).map(toInt);
},
getTransitionDelays: function(){
return this.getStyle('transitionDelay').split(splitter).map(toInt);
},
getTransitionTime: function(){
var durations = this.getTransitionDurations(),
delays = this.getTransitionDelays(),
max = 0;
for (var i = 0, length = Math.max(durations.length, delays.length); i < length; i++)
max = Math.max(max, (durations[i] || 0) + (delays[i] || 0));
return max;
},
setTransition: function(properties){
if (!properties) return this;
if (properties.property != null) this.setStyle('transitionProperty', properties.property);
if (properties.timingFunction != null) this.setStyle('transitionTimingFunction', properties.timingFunction)
if (properties.duration != null) this.setStyle('transitionDuration', properties.duration);
if (properties.delay != null) this.setStyle('transitionDelay', properties.delay);
return this;
},
getTransition: function(){
return this.getStyles(
'transitionProperty', 'transitionTimingFunction',
'transitionDuration', 'transitionDelay'
);
},
resetTransition: function(){
return this.setStyles({
transitionProperty: '',
transitionTimingFunction: '',
transitionDuration: '',
transitionDelay: ''
});
},
hasTransition: function(){
return !!(this.getStyle('transitionDuration') || this.getStyle('transitionDelay'));
},
cancelTransition: function(){
var properties = this.getTransitionProperties(),
property, length, i;
if (properties.contains('all')) properties = Array.slice(this.style); // copy because changing styles reorders
for (i = 0, length = properties.length; i < length; i++){
property = properties[i];
var camelCased = property.camelCase();
if (camelCased == durationProperty || camelCased == transitionProperty) continue;
this.setStyle(property, this.getComputedStyle(property));
}
return this;
}
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment