transition-native.js revision 416ff6e8477a5950c56e04adea6abf838140a852
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington* Provides the transition method for Node.
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington* Transition has no API of its own, but adds the transition method to Node.
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington* @module transition
d4ef65050feac78554addf6e16a06c6e2e0bd331Brian Wellington* @requires node-style
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington * A class for constructing transition instances.
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington * Adds the "transition" method to Node.
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington * @class Transition
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington * @constructor
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington property = property.replace(/-([a-z])/gi, function(m0, m1) {
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington property = property.replace(/([A-Z]?)([a-z]+)([A-Z]?)/g, function(m0, m1, m2, m3) {
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington var str = ((m1) ? '-' + m1.toLowerCase() : '') + m2;
0b062f4990db5cc6db2fe3398926f71b92a67407Brian WellingtonY.Array.each(VENDORS, function(val) { // then vendor specific
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington if (property in DOCUMENT[DOCUMENT_ELEMENT].style) {
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington VENDOR_PREFIX = Transition._toHyphen(val) + '-';
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington Transition.supported = true; // TODO: remove
0b062f4990db5cc6db2fe3398926f71b92a67407Brian WellingtonTRANSITION_CAMEL = CAMEL_VENDOR_PREFIX + TRANSITION_CAMEL;
0b062f4990db5cc6db2fe3398926f71b92a67407Brian WellingtonTRANSITION_PROPERTY_CAMEL = CAMEL_VENDOR_PREFIX + 'TransitionProperty';
0b062f4990db5cc6db2fe3398926f71b92a67407Brian WellingtonTRANSITION_PROPERTY = VENDOR_PREFIX + 'transition-property';
0b062f4990db5cc6db2fe3398926f71b92a67407Brian WellingtonTRANSITION_DURATION = VENDOR_PREFIX + 'transition-duration';
0b062f4990db5cc6db2fe3398926f71b92a67407Brian WellingtonTRANSITION_TIMING_FUNCTION = VENDOR_PREFIX + 'transition-timing-function';
0b062f4990db5cc6db2fe3398926f71b92a67407Brian WellingtonTRANSITION_DELAY = VENDOR_PREFIX + 'transition-delay';
0b062f4990db5cc6db2fe3398926f71b92a67407Brian WellingtonON_TRANSITION_END = 'on' + CAMEL_VENDOR_PREFIX.toLowerCase() + 'transitionend';
0b062f4990db5cc6db2fe3398926f71b92a67407Brian WellingtonTRANSITION_END = VENDOR_TRANSITION_END[CAMEL_VENDOR_PREFIX] || TRANSITION_END;
0b062f4990db5cc6db2fe3398926f71b92a67407Brian WellingtonTRANSFORM_CAMEL = CAMEL_VENDOR_PREFIX + 'Transform';
0b062f4990db5cc6db2fe3398926f71b92a67407Brian WellingtonTransition._reKeywords = /^(?:node|duration|iterations|easing|delay|on|onstart|onend)$/i;
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington node._transition = anim; // cache for reuse
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington config.duration: anim.constructor.DEFAULT_DURATION;
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington config.delay: anim.constructor.DEFAULT_DELAY;
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington anim._easing = config.easing || anim.constructor.DEFAULT_EASING;
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington anim._count = 0; // track number of animated properties
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington // might just be a value
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington if (config && config.value !== undefined) {
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington val = val.call(nodeInstance, nodeInstance);
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington // take control if another transition owns this property
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington attr.transition._count--; // remapping attr to this transition
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington anim._count++; // properties per transition
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington // make 0 async and fire events
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington dur = ((typeof config.duration != 'undefined') ? config.duration :
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington delay: (typeof config.delay != 'undefined') ? config.delay :
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington // native end event doesnt fire when setting to same value
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington // supplementing with timer
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington // val may be a string or number (height: 0, etc), but computedStyle is always string
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington computed = Y.DOM.getComputedStyle(node, prop);
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington compareVal = (typeof val === 'string') ? computed : parseFloat(computed);
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington if (Transition.useNative && compareVal === val) {
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington attrs = Transition._nodeAttrs[Y.stamp(anim._node)];
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington if (config.transform && !config[TRANSFORM_CAMEL]) {
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington config[TRANSFORM_CAMEL] = config.transform;
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington if (config.hasOwnProperty(attr) && !Transition._reKeywords.test(attr)) {
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington // when size is auto or % webkit starts from zero instead of computed
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington // (https://bugs.webkit.org/show_bug.cgi?id=16020)
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington // TODO: selective set
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington Y.DOM.setStyle(node, attr, Y.DOM.getComputedStyle(node, attr));
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington * Starts or an animation.
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington * @method run
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington //anim._node.fire('transition:start', data);
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington cssTransition = computed[Transition._toCamel(TRANSITION_PROPERTY)],
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington transitionText = TRANSITION_PROPERTY + ': ',
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington easing = TRANSITION_TIMING_FUNCTION + ': ',
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington // preserve existing transitions
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington duration += computed[Transition._toCamel(TRANSITION_DURATION)] + ',';
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington easing += computed[Transition._toCamel(TRANSITION_TIMING_FUNCTION)] + ',';
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington delay += computed[Transition._toCamel(TRANSITION_DELAY)] + ',';
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington // run transitions mapped to this instance
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington if ((attr = attrs[name]) && attr.transition === anim) {
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington if (name in node.style) { // only native styles allowed
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington duration += anim._prepDur(attr.duration) + ',';
0b062f4990db5cc6db2fe3398926f71b92a67407Brian Wellington cssText += hyphy + ': ' + attr.value + '; ';
var anim = this,
data = {
if (node) {
if (callback) {
} else if (callback) {
value = node.ownerDocument.defaultView.getComputedStyle(node, '')[Transition._toCamel(TRANSITION_PROPERTY)];
_onNativeEnd: function(e) {
var node = this,
data,
if (anim) {
data = {
destroy: function() {
var anim = this,
if (node) {
* @param {Object} config An object containing one or more style properties, a duration and an easing.
prop;
config = null;
if (typeof name !== 'string' && !name.push) { // named effect or array of effects supercedes default
else if (name && !Y.Transition) { Y.log('unable to transition show; missing transition module', 'warn', 'node'); }
if (fn) {
if (callback) {
config = null;
if (typeof name !== 'string' && !name.push) { // named effect or array of effects supercedes default
} else if (name && !Y.Transition) { Y.log('unable to transition hide; missing transition module', 'warn', 'node'); // end if on nex
this._hide();
* @param {Object} config An object containing one or more style properties, a duration and an easing.
* @param {Function} callback A function to run after the transition has completed. The callback fires
node;
name = null;
if (on) {
this._show();
node;
fadeOut: {
fadeIn: {
sizeOut: {
sizeIn: {
on: {
start: function() {
end: function() {
delete this._transitionOverflow;