2015-12-01 20:22:36 +03:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
|
|
|
|
|
|
|
var Ripples = (function ($) {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ------------------------------------------------------------------------
|
|
|
|
* Constants
|
|
|
|
* ------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
var NAME = 'ripples';
|
2015-12-03 00:03:02 +03:00
|
|
|
var DATA_KEY = 'mdb.' + NAME;
|
2015-12-01 20:22:36 +03:00
|
|
|
var JQUERY_NO_CONFLICT = $.fn[NAME];
|
2015-12-03 00:03:02 +03:00
|
|
|
|
|
|
|
var ClassName = {
|
|
|
|
CONTAINER: 'ripple-container',
|
|
|
|
DECORATOR: 'ripple-decorator'
|
|
|
|
};
|
2015-12-01 20:22:36 +03:00
|
|
|
|
|
|
|
var Selector = {
|
2015-12-03 00:03:02 +03:00
|
|
|
CONTAINER: '.' + ClassName.CONTAINER,
|
|
|
|
DECORATOR: '.' + ClassName.DECORATOR //,
|
2015-12-01 20:22:36 +03:00
|
|
|
};
|
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
var Default = {
|
|
|
|
container: {
|
|
|
|
template: '<div class=\'' + ClassName.CONTAINER + '\'></div>'
|
|
|
|
},
|
|
|
|
decorator: {
|
|
|
|
template: ClassName.DECORATOR + '\'></div>'
|
|
|
|
},
|
|
|
|
trigger: {
|
|
|
|
start: 'mousedown touchstart',
|
|
|
|
end: 'mouseup mouseleave touchend'
|
|
|
|
},
|
|
|
|
touchUserAgentRegex: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i,
|
|
|
|
duration: 500
|
2015-12-01 20:22:36 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ------------------------------------------------------------------------
|
|
|
|
* Class Definition
|
|
|
|
* ------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
var Ripples = (function () {
|
2015-12-03 00:03:02 +03:00
|
|
|
function Ripples(element, config) {
|
2015-12-01 20:22:36 +03:00
|
|
|
_classCallCheck(this, Ripples);
|
|
|
|
|
|
|
|
this.element = $(element);
|
2015-12-03 00:03:02 +03:00
|
|
|
this.config = $.extend({}, Default, config);
|
2015-12-01 20:22:36 +03:00
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
// attach initial listener
|
|
|
|
this.element.on(this.config.triggerStart, this._onStartRipple);
|
2015-12-01 20:22:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ------------------------------------------------------------------------
|
|
|
|
* jQuery
|
|
|
|
* ------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
_createClass(Ripples, [{
|
|
|
|
key: 'dispose',
|
|
|
|
value: function dispose() {
|
|
|
|
$.removeData(this.element, DATA_KEY);
|
|
|
|
this.element = null;
|
2015-12-03 00:03:02 +03:00
|
|
|
this.containerElement = null;
|
|
|
|
this.decoratorElement = null;
|
|
|
|
this.config = null;
|
2015-12-01 20:22:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// private
|
|
|
|
|
|
|
|
}, {
|
2015-12-03 00:03:02 +03:00
|
|
|
key: '_onStartRipple',
|
|
|
|
value: function _onStartRipple(event) {
|
|
|
|
var _this = this;
|
2015-12-01 20:22:36 +03:00
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
// Verify if the user is just touching on a device and return if so
|
|
|
|
if (this.isTouch() && event.type === 'mousedown') {
|
2015-12-01 20:22:36 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
// Find or create the ripple container element
|
|
|
|
this._findOrCreateContainer();
|
2015-12-01 20:22:36 +03:00
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
// Get relY and relX positions of the container element
|
|
|
|
var relY = this._getRelY(event);
|
|
|
|
var relX = this._getRelX(event);
|
2015-12-01 20:22:36 +03:00
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
// If relY and/or relX are false, return the event
|
2015-12-01 20:22:36 +03:00
|
|
|
if (!relY && !relX) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
// set the location and color each time (even if element is cached)
|
|
|
|
this.decoratorElement.css({
|
|
|
|
'left': relX,
|
|
|
|
'top': relY,
|
|
|
|
'background-color': this._getRipplesColor()
|
|
|
|
});
|
2015-12-01 20:22:36 +03:00
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
// Make sure the ripple has the styles applied (ugly hack but it works)
|
|
|
|
this._forceStyleApplication();
|
2015-12-01 20:22:36 +03:00
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
// Turn on the ripple animation
|
|
|
|
this.rippleOn();
|
2015-12-01 20:22:36 +03:00
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
// Call the rippleEnd function when the transition 'on' ends
|
2015-12-01 20:22:36 +03:00
|
|
|
setTimeout(function () {
|
2015-12-03 00:03:02 +03:00
|
|
|
_this.rippleEnd();
|
|
|
|
}, this.config.duration);
|
2015-12-01 20:22:36 +03:00
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
// Detect when the user leaves the element (attach only when necessary for performance)
|
|
|
|
this.element.on(this.config.triggerEnd, function () {
|
|
|
|
_this.decoratorElement.data('mousedown', 'off');
|
2015-12-01 20:22:36 +03:00
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
if (_this.decoratorElement.data('animating') === 'off') {
|
|
|
|
_this.rippleOut();
|
2015-12-01 20:22:36 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2015-12-03 00:03:02 +03:00
|
|
|
}, {
|
|
|
|
key: '_findOrCreateContainer',
|
|
|
|
value: function _findOrCreateContainer() {
|
|
|
|
if (!this.containerElement || !this.containerElement.length > 0) {
|
|
|
|
this.element.append(this.config.container.template);
|
|
|
|
this.containerElement = this.element.find(Selector.CONTAINER);
|
|
|
|
}
|
|
|
|
|
|
|
|
// always add the rippleElement, it is always removed
|
|
|
|
this.containerElement.append(this.config.element.template);
|
|
|
|
this.decoratorElement = this.containerElement.find(Selector.DECORATOR);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure the ripple has the styles applied (ugly hack but it works)
|
|
|
|
}, {
|
|
|
|
key: '_forceStyleApplication',
|
|
|
|
value: function _forceStyleApplication() {
|
|
|
|
return window.getComputedStyle(this.decoratorElement[0]).opacity;
|
|
|
|
}
|
2015-12-01 20:22:36 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the relX
|
|
|
|
*/
|
|
|
|
}, {
|
|
|
|
key: '_getRelX',
|
2015-12-03 00:03:02 +03:00
|
|
|
value: function _getRelX(event) {
|
|
|
|
var wrapperOffset = this.containerElement.offset();
|
2015-12-01 20:22:36 +03:00
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
var result = null;
|
2015-12-01 20:22:36 +03:00
|
|
|
if (!this.isTouch()) {
|
2015-12-03 00:03:02 +03:00
|
|
|
// Get the mouse position relative to the ripple wrapper
|
|
|
|
result = event.pageX - wrapperOffset.left;
|
2015-12-01 20:22:36 +03:00
|
|
|
} else {
|
2015-12-03 00:03:02 +03:00
|
|
|
// Make sure the user is using only one finger and then get the touch
|
|
|
|
// position relative to the ripple wrapper
|
2015-12-01 20:22:36 +03:00
|
|
|
event = event.originalEvent;
|
|
|
|
|
|
|
|
if (event.touches.length === 1) {
|
2015-12-03 00:03:02 +03:00
|
|
|
result = event.touches[0].pageX - wrapperOffset.left;
|
|
|
|
} else {
|
|
|
|
result = false;
|
2015-12-01 20:22:36 +03:00
|
|
|
}
|
|
|
|
}
|
2015-12-03 00:03:02 +03:00
|
|
|
|
|
|
|
return result;
|
2015-12-01 20:22:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the relY
|
|
|
|
*/
|
|
|
|
}, {
|
|
|
|
key: '_getRelY',
|
2015-12-03 00:03:02 +03:00
|
|
|
value: function _getRelY(event) {
|
|
|
|
var containerOffset = this.containerElement.offset();
|
|
|
|
var result = null;
|
2015-12-01 20:22:36 +03:00
|
|
|
|
|
|
|
if (!this.isTouch()) {
|
|
|
|
/**
|
|
|
|
* Get the mouse position relative to the ripple wrapper
|
|
|
|
*/
|
2015-12-03 00:03:02 +03:00
|
|
|
result = event.pageY - containerOffset.top;
|
2015-12-01 20:22:36 +03:00
|
|
|
} else {
|
|
|
|
/**
|
|
|
|
* Make sure the user is using only one finger and then get the touch
|
|
|
|
* position relative to the ripple wrapper
|
|
|
|
*/
|
|
|
|
event = event.originalEvent;
|
|
|
|
|
|
|
|
if (event.touches.length === 1) {
|
2015-12-03 00:03:02 +03:00
|
|
|
result = event.touches[0].pageY - containerOffset.top;
|
|
|
|
} else {
|
|
|
|
result = false;
|
2015-12-01 20:22:36 +03:00
|
|
|
}
|
|
|
|
}
|
2015-12-03 00:03:02 +03:00
|
|
|
|
|
|
|
return result;
|
2015-12-01 20:22:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the ripple color
|
|
|
|
*/
|
|
|
|
}, {
|
|
|
|
key: '_getRipplesColor',
|
2015-12-03 00:03:02 +03:00
|
|
|
value: function _getRipplesColor() {
|
|
|
|
var color = this.element.data('ripple-color') ? this.element.data('ripple-color') : window.getComputedStyle(this.element[0]).color;
|
2015-12-01 20:22:36 +03:00
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Verify if the client is using a mobile device
|
|
|
|
*/
|
|
|
|
}, {
|
|
|
|
key: 'isTouch',
|
|
|
|
value: function isTouch() {
|
2015-12-03 00:03:02 +03:00
|
|
|
return this.config.touchUserAgentRegex.test(navigator.userAgent);
|
2015-12-01 20:22:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* End the animation of the ripple
|
|
|
|
*/
|
|
|
|
}, {
|
|
|
|
key: 'rippleEnd',
|
2015-12-03 00:03:02 +03:00
|
|
|
value: function rippleEnd() {
|
|
|
|
this.decoratorElement.data('animating', 'off');
|
2015-12-01 20:22:36 +03:00
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
if (this.decoratorElement.data('mousedown') === 'off') {
|
|
|
|
this.rippleOut(this.decoratorElement);
|
2015-12-01 20:22:36 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Turn off the ripple effect
|
|
|
|
*/
|
|
|
|
}, {
|
|
|
|
key: 'rippleOut',
|
2015-12-03 00:03:02 +03:00
|
|
|
value: function rippleOut() {
|
|
|
|
var _this2 = this;
|
2015-12-01 20:22:36 +03:00
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
this.decoratorElement.off();
|
|
|
|
|
|
|
|
if (Util.transitionEndSupported()) {
|
|
|
|
this.decoratorElement.addClass('ripple-out');
|
2015-12-01 20:22:36 +03:00
|
|
|
} else {
|
2015-12-03 00:03:02 +03:00
|
|
|
this.decoratorElement.animate({ 'opacity': 0 }, 100, function () {
|
|
|
|
_this2.decoratorElement.triggerStart('transitionend');
|
2015-12-01 20:22:36 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-12-03 00:03:02 +03:00
|
|
|
this.decoratorElement.on(Util.transitionEndSelector(), function () {
|
|
|
|
_this2.decoratorElement.remove();
|
|
|
|
_this2.decoratorElement = null;
|
2015-12-01 20:22:36 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Turn on the ripple effect
|
|
|
|
*/
|
|
|
|
}, {
|
|
|
|
key: 'rippleOn',
|
2015-12-03 00:03:02 +03:00
|
|
|
value: function rippleOn() {
|
|
|
|
var _this3 = this;
|
|
|
|
|
|
|
|
var size = this._getNewSize();
|
|
|
|
|
|
|
|
if (Util.transitionEndSupported()) {
|
|
|
|
this.decoratorElement.css({
|
|
|
|
'-ms-transform': 'scale(' + size + ')',
|
|
|
|
'-moz-transform': 'scale(' + size + ')',
|
|
|
|
'-webkit-transform': 'scale(' + size + ')',
|
|
|
|
'transform': 'scale(' + size + ')'
|
|
|
|
}).addClass('ripple-on').data('animating', 'on').data('mousedown', 'on');
|
2015-12-01 20:22:36 +03:00
|
|
|
} else {
|
2015-12-03 00:03:02 +03:00
|
|
|
this.decoratorElement.animate({
|
|
|
|
'width': Math.max(this.element.outerWidth(), this.element.outerHeight()) * 2,
|
|
|
|
'height': Math.max(this.element.outerWidth(), this.element.outerHeight()) * 2,
|
|
|
|
'margin-left': Math.max(this.element.outerWidth(), this.element.outerHeight()) * -1,
|
|
|
|
'margin-top': Math.max(this.element.outerWidth(), this.element.outerHeight()) * -1,
|
|
|
|
'opacity': 0.2
|
|
|
|
}, this.config.duration, function () {
|
|
|
|
_this3.decoratorElement.triggerStart('transitionend');
|
2015-12-01 20:22:36 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the new size based on the element height/width and the ripple width
|
|
|
|
*/
|
2015-12-03 00:03:02 +03:00
|
|
|
}, {
|
2015-12-01 20:22:36 +03:00
|
|
|
key: '_getNewSize',
|
2015-12-03 00:03:02 +03:00
|
|
|
value: function _getNewSize() {
|
|
|
|
return Math.max(this.element.outerWidth(), this.element.outerHeight()) / this.decoratorElement.outerWidth() * 2.5;
|
2015-12-01 20:22:36 +03:00
|
|
|
}
|
2015-12-03 00:03:02 +03:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// static
|
|
|
|
|
|
|
|
}], [{
|
2015-12-01 20:22:36 +03:00
|
|
|
key: '_jQueryInterface',
|
2015-12-03 00:03:02 +03:00
|
|
|
value: function _jQueryInterface(config) {
|
|
|
|
var _this4 = this;
|
|
|
|
|
2015-12-01 20:22:36 +03:00
|
|
|
return this.each(function () {
|
2015-12-03 00:03:02 +03:00
|
|
|
var element = $(_this4);
|
|
|
|
var data = element.data(DATA_KEY);
|
2015-12-01 20:22:36 +03:00
|
|
|
|
|
|
|
if (!data) {
|
2015-12-03 00:03:02 +03:00
|
|
|
data = new Ripples(_this4, config);
|
|
|
|
element.data(DATA_KEY, data);
|
2015-12-01 20:22:36 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}]);
|
|
|
|
|
|
|
|
return Ripples;
|
|
|
|
})();
|
|
|
|
|
|
|
|
$.fn[NAME] = Ripples._jQueryInterface;
|
|
|
|
$.fn[NAME].Constructor = Ripples;
|
|
|
|
$.fn[NAME].noConflict = function () {
|
|
|
|
$.fn[NAME] = JQUERY_NO_CONFLICT;
|
|
|
|
return Ripples._jQueryInterface;
|
|
|
|
};
|
|
|
|
|
|
|
|
return Ripples;
|
|
|
|
})(jQuery);
|
|
|
|
//# sourceMappingURL=ripples.js.map
|