chicago
Version:
A front-end JavaScript library for user-interface developers.
174 lines (148 loc) • 4.72 kB
JavaScript
// @name: Chicago.events.transition
// @description: Triggers an event and executes callback functions at certain points during the CSS animation (using the `animation` property) of a DOM object
// @since: 1.0.0-beta
// @todo: Add `properties` as a default option to list of values
// @todo: Value would be array of transition-properties (as strings) to listen for.
transition : {
defaults : {
start : function(property) {},
progress : function(property, duration, value) {},
complete : function(property) {},
},
setup : function( data, namespaces, eventHandle ) {
var uid = _c.utils.uid( 'transition' ),
ele = _c.$(this),
keys = {
uid : 'chicago.event.transition.uid',
base : 'chicago.event.' + uid,
event : 'chicago.event.' + uid + '.event',
info : 'chicago.event.' + uid + '.info',
},
intervalCount = 15,
_event = {
initalValues : {}
},
tracker = _c.win.performace ? _c.win.performace.now : _c.utils.now;
data = _c.extend( {}, _c.$.event.special.transition.defaults, data );
function getTransitionData() {
var info = ele.data( keys.info );
if( info ) {
return info;
}
info = {};
var transition = ele.css('transition').split( ',' );
for( var i = 0; i < transition.length; i++ ) {
var values = transition[i].trim().split( ' ' ),
property = values[0];
if( ! info.hasOwnProperty( property ) ) {
info[ property ] = {
duration : _c.utils.stringToMilliseconds( values[1] ),
function : values[2],
delay : _c.utils.stringToMilliseconds( values[3] ),
value : _c.utils.getCSSValue( ele, property )
};
}
}
ele.data( keys.info, info );
return info;
}
function removeDataForProperty( property ) {
var keyBase = keys.base + '.' + property,
_keys = {
bindStart : keyBase + '.did.bind.start',
didStart : keyBase + '.did.start',
didStartAt : keyBase + '.did.start.at',
progressValue : keyBase + '.progress.value'
};
for( var key in _keys ) {
var string = _keys[ key ];
ele.removeData( string );
}
}
function setInitialValues(property) {
if( ! property ) {
for( var prop in getTransitionData() ) {
_event.initalValues[prop] = _c.utils.getCSSValue( ele, prop );
}
} else {
_event.initalValues[property] = _c.utils.getCSSValue( ele, property );
}
}
// Set UID
ele.data( keys.uid, uid );
if( ! ele.data( keys.event ) ) {
var did = {
begin : {},
end : {}
},
diff = 0;
function completeCallback( property, cssValue, elapsedTime ) {
diff = 0;
did.end[property] = {
time : tracker()
};
setInitialValues(property);
delete did.begin[property];
data.complete.call( ele[0], property, cssValue, elapsedTime );
ele.trigger( 'transition' );
}
setInitialValues();
ele.on(_c.support.transition.end, function(e) {
var property = e.originalEvent.propertyName,
cssValue = _c.utils.getCSSValue( ele, property ),
info = getTransitionData(),
elapsedTime = info[ property ].duration;
completeCallback( property, cssValue, elapsedTime );
});
// Begin the interval cycle
_event.interval = win.setInterval(function() {
info = getTransitionData();
for( var property in info ) {
// loop values
var initialValue = _event.initalValues[property],
currentValue = _c.utils.getCSSValue( ele, property ),
obj = info[ property ];
if( diff && did.begin[property] ) {
diff = tracker() - did.begin[property].time;
}
// transition did begin for property
if( ! did.begin[property] && currentValue != initialValue ) {
did.begin[property] = {
time : tracker()
};
if( did.end[property] ) {
delete did.end[property];
}
data.start.call( ele[0], property, initialValue );
// transition did progress for property
} else if( did.begin[property] && ! did.end[property] && diff < (obj.duration + 1) ) {
data.progress.call( ele[0], property, currentValue, diff );
}
}
}, intervalCount);
ele.data( keys.event, _event );
}
return true;
},
teardown: function() {
var uid = _c.$(this).data( 'chicago.event.transition.uid' ),
keys = {
uid : 'chicago.event.transition.uid',
base : 'chicago.event.' + uid,
event : 'chicago.event.' + uid + '.event',
info : 'chicago.event.' + uid + '.info',
};
for( var k in keys ) {
var key = keys[ k ],
value = _c.$(this).data( key );
// Clear the interval timer
if( k === 'event' && value && value.interval ) {
win.clearInterval( value.interval );
}
// Remove all data
if( value ) {
_c.$(this).removeData( key );
}
}
}
},