UNPKG

chicago

Version:

A front-end JavaScript library for user-interface developers.

174 lines (148 loc) 4.72 kB
// @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 ); } } } },