social-likes-nojq/gh-pages/tamia/vendor/transition-events.js

213 lines
7.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright 2012 Andrey “A.I.” Sitnik <andrey@sitnik.ru>,
* sponsored by Evil Martians.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
;(function($) {
"use strict";
// Common methods and properties for jQuery Transition Events plugin.
// Mostly for internal usage, but maybe helpful for some hack stuff:
//
// if ( $.Transitions.isSupported() ) {
// // CSS Transitions is supported
// }
$.Transitions = {
// Hash of property name to event name with vendor prefixes.
// It is used to detect prefix.
_names: {
// Webkit must be on bottom, because Opera try to use webkit
// prefix.
'transition': 'transitionend',
'OTransition': 'oTransitionEnd',
'WebkitTransition': 'webkitTransitionEnd',
'MozTransition': 'transitionend'
},
// Return array of milliseconds for CSS value of `transition-duration`.
// Its used in `$.fn.afterTransition`.
_parseTimes: function (string) {
var value, array = string.split(/,\s*/);
for (var i = 0; i < array.length; i++) {
value = array[i];
array[i] = parseFloat(value);
if ( value.match(/\ds/) ) {
array[i] = array[i] * 1000;
}
}
return array;
},
// Autodetect vendor prefix and return `transitionend` event name.
//
// If browser didnt support CSS Transitions it will return `false`.
getEvent: function () {
var finded = false;
for ( var prop in this._names ) {
if ( typeof(document.body.style[prop]) != 'undefined' ) {
finded = this._names[prop];
break;
}
}
this.getEvent = function () {
return finded;
};
return finded;
},
// Alias to vendor prefixed `requestAnimationFrame`. Will be replace
// by native function after first call.
animFrame: function (callback) {
var raf = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame;
if ( raf ) {
this.animFrame = function (callback) {
return raf.call(window, callback);
};
} else {
this.animFrame = function (callback) {
return setTimeout(callback, 10);
};
}
return this.animFrame(callback);
},
// Return `true` if browser support CSS Transitions.
isSupported: function () {
return this.getEvent() !== false;
}
}
// jQuery node methods.
$.extend($.fn, {
// Call `callback` after CSS Transition finish
// `delay + (durationPart * duration)`. It will call `callback` only
// once, in difference from `transitionEnd`.
//
// $('.show-video').click(function () {
// $('.slider').addClass('video-position').afterTransition(
// function () { autoPlayVideo(); });
// });
//
// You can set `durationPart` to call `callback` in the middle of
// transition:
//
// $('.fliper').addClass('rotate').afterTransition(0.5, function () {
// $(this).find('.backface').show();
// });
//
// Callback will get object with `propertyName` and `elapsedTime`
// properties. If transition is set to difference properties, it will
// be called on every property.
//
// This method doesnt check, that transition is really finished (it can
// be canceled in the middle).
afterTransition: function (durationPart, callback) {
if ( typeof(callback) == 'undefined' ) {
callback = durationPart;
durationPart = 1;
}
if ( !$.Transitions.isSupported() ) {
for (var i = 0; i < this.length; i++) {
callback.call(this[i], {
type: 'aftertransition',
elapsedTime: 0,
propertyName: '',
currentTarget: this[i]
});
}
return this;
}
for (var i = 0; i < this.length; i++) {
var el = $(this[i]);
var props = el.css('transition-property').split(/,\s*/);
var durations = el.css('transition-duration');
var delays = el.css('transition-delay');
durations = $.Transitions._parseTimes(durations);
delays = $.Transitions._parseTimes(delays);
var prop, duration, delay, after, elapsed;
for (var j = 0; j < props.length; j++) {
prop = props[j];
duration = durations[ durations.length == 1 ? 0 : j ];
delay = delays[ delays.length == 1 ? 0 : j ];
after = delay + (duration * durationPart);
elapsed = duration * durationPart / 1000;
(function (el, prop, after, elapsed) {
setTimeout(function () {
$.Transitions.animFrame(function () {
callback.call(el[0], {
type: 'aftertransition',
elapsedTime: elapsed,
propertyName: prop,
currentTarget: el[0]
});
});
}, after);
})(el, prop, after, elapsed);
}
}
return this;
},
// Set `callback` to listen every CSS Transition finish.
// It will call `callback` on every finished transition,
// in difference from `afterTransition`.
//
// It just bind to `transitionend` event, but detect vendor prefix.
//
// Callback will get event object with `propertyName` and `elapsedTime`
// properties. If transition is set to difference properties, it will
// be called on every property.
//
// Note, that `callback` will get original event object, not from
// jQuery.
//
// var slider = $('.slider').transitionEnd(function () {
// if ( slider.hasClass('video-position') ) {
// autoPlayVideo();
// }
// });
//
// $('.show-video').click(function () {
// slider.addClass('video-position');
// });
//
// If transition will be canceled before finish, event wont be fired.
transitionEnd: function (callback) {
for (var i = 0; i < this.length; i++) {
this[i].addEventListener($.Transitions.getEvent(), function (e) {
callback.call(this, e);
});
}
return this;
}
});
}).call(this, jQuery);