mdb-ui-kit/scripts/ripples.js

128 lines
5.0 KiB
JavaScript
Raw Normal View History

2014-09-17 10:18:00 +04:00
/* Copyright 2014+, Federico Zivolo, LICENSE at https://github.com/FezVrasta/bootstrap-material-design/blob/master/LICENSE.md */
2014-09-18 11:18:45 +04:00
/* globals CustomEvent, navigator */
var ripples = {
2014-08-25 15:57:22 +04:00
init : function(withRipple) {
"use strict";
// Cross browser matches function
function matchesSelector(dom_element, selector) {
var matches = dom_element.matches || dom_element.matchesSelector || dom_element.webkitMatchesSelector || dom_element.mozMatchesSelector || dom_element.msMatchesSelector || dom_element.oMatchesSelector;
return matches.call(dom_element, selector);
}
2014-08-25 15:57:22 +04:00
// animations time
var rippleOutTime = 100,
rippleStartTime = 500;
// Helper to bind events on dynamically created elements
var bind = function(event, selector, callback) {
document.addEventListener(event, function(e) {
var target = (typeof e.detail !== "number") ? e.detail : e.target;
if (matchesSelector(target, selector)) {
2014-08-25 15:57:22 +04:00
callback(e, target);
}
});
};
var rippleStart = function(e, target) {
// Init variables
var $rippleWrapper = (matchesSelector(target, ".ripple-wrapper")) ? target : target.parentNode,
2014-08-25 15:57:22 +04:00
$el = $rippleWrapper.parentNode,
$ripple = document.createElement("div"),
elPos = $el.getBoundingClientRect(),
mousePos = {x: e.clientX - elPos.left, y: e.clientY - elPos.top},
scale = "transform:scale(" + Math.round($rippleWrapper.offsetWidth / 5) + ")",
rippleEnd = new CustomEvent("rippleEnd", {detail: $ripple}),
refreshElementStyle;
// Set ripple class
$ripple.className = "ripple";
// Move ripple to the mouse position
$ripple.setAttribute("style", "left:" + mousePos.x + "px; top:" + mousePos.y + "px;");
// Insert new ripple into ripple wrapper
$rippleWrapper.appendChild($ripple);
// Make sure the ripple has the class applied (ugly hack but it works)
refreshElementStyle = window.getComputedStyle($ripple).opacity;
// Let other funtions know that this element is animating
$ripple.dataset.animating = 1;
// Set scale value to ripple and animate it
$ripple.className = "ripple ripple-on";
$ripple.setAttribute("style", $ripple.getAttribute("style") + ["-ms-" + scale,"-moz-" + scale,"-webkit-" + scale,scale].join(";"));
2014-09-18 11:18:45 +04:00
// Dirty fix for Firefox... seems like absolute elements inside <A> tags do not trigger the "click" event
2014-09-23 12:00:58 +04:00
if (/firefox|crios|ip(ad|hone|od)/i.test(navigator.userAgent)) {
2014-09-18 11:18:45 +04:00
$el.click();
}
2014-08-25 15:57:22 +04:00
// This function is called when the animation is finished
setTimeout(function() {
// Let know to other functions that this element has finished the animation
$ripple.dataset.animating = 0;
document.dispatchEvent(rippleEnd);
}, rippleStartTime);
};
var rippleOut = function($ripple) {
// Clear previous animation
$ripple.className = "ripple ripple-on ripple-out";
// Let ripple fade out (with CSS)
setTimeout(function() {
$ripple.remove();
}, rippleOutTime);
};
// Helper, need to know if mouse is up or down
var mouseDown = false;
document.body.onmousedown = function() {
mouseDown = true;
};
document.body.onmouseup = function() {
mouseDown = false;
};
// Append ripple wrapper if not exists already
var rippleInit = function(e, target) {
if (target.getElementsByClassName("ripple-wrapper").length === 0) {
target.className += " withripple";
var $rippleWrapper = document.createElement("div");
$rippleWrapper.className = "ripple-wrapper";
target.appendChild($rippleWrapper);
rippleStart(e, $rippleWrapper);
}
};
// Events handler
// init RippleJS and start ripple effect on mousedown
bind("mousedown", withRipple, rippleInit);
2014-09-18 11:18:45 +04:00
2014-08-25 15:57:22 +04:00
// start ripple effect on mousedown
2014-08-25 18:41:22 +04:00
bind("mousedown", ".ripple-wrapper, .ripple-wrapper .ripple", rippleStart);
2014-08-25 15:57:22 +04:00
// if animation ends and user is not holding mouse then destroy the ripple
2014-08-25 18:41:22 +04:00
bind("rippleEnd", ".ripple-wrapper, .ripple-wrapper .ripple", function(e, $ripple) {
2014-08-25 15:57:22 +04:00
if (!mouseDown) {
rippleOut($ripple);
}
});
// Destroy ripple when mouse is not holded anymore if the ripple still exists
2014-08-25 18:41:22 +04:00
bind("mouseup", ".ripple-wrapper, .ripple-wrapper .ripple", function(e, $ripple) {
2014-08-25 15:57:22 +04:00
if ($ripple.dataset.animating != 1) {
rippleOut($ripple);
}
});
}
};