improved transitions.

This commit is contained in:
Federico Zivolo 2014-08-25 13:57:22 +02:00
parent c2d4a54b53
commit 96d11df81f
3 changed files with 99 additions and 95 deletions

View File

@ -36,7 +36,7 @@
opacity: 1; opacity: 1;
} }
.ripple.ripple-out { .ripple.ripple-out {
-webkit-transition: opacity 1s linear 0s !important; -webkit-transition: opacity 0.1s linear 0s !important;
transition: opacity 0.8s linear 0s !important; transition: opacity 0.1s linear 0s !important;
opacity: 0; opacity: 0;
} }

View File

@ -1,7 +1,7 @@
// out: ../css-compiled/ripples.css // out: ../css-compiled/ripples.css
.withripple { .withripple {
position: relative; position: relative;
} }
.ripple-wrapper { .ripple-wrapper {
position: absolute; position: absolute;
@ -30,14 +30,14 @@
opacity: 0; opacity: 0;
} }
.ripple.ripple-on { .ripple.ripple-on {
-webkit-transition: opacity 0.15s ease-in 0s, -webkit-transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s; -webkit-transition: opacity 0.15s ease-in 0s, -webkit-transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
-ms-transition: opacity 0.15s ease-in 0s, -ms-transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s; -ms-transition: opacity 0.15s ease-in 0s, -ms-transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
-moz-transition: opacity 0.15s ease-in 0s, -moz-transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s; -moz-transition: opacity 0.15s ease-in 0s, -moz-transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
transition: opacity 0.15s ease-in 0s, transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s; transition: opacity 0.15s ease-in 0s, transform 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
opacity: 1; opacity: 1;
} }
.ripple.ripple-out { .ripple.ripple-out {
-webkit-transition: opacity 1s linear 0s !important; -webkit-transition: opacity 0.1s linear 0s !important;
transition: opacity 0.8s linear 0s !important; transition: opacity 0.1s linear 0s !important;
opacity: 0; opacity: 0;
} }

View File

@ -1,110 +1,114 @@
/* globals CustomEvent */ /* globals CustomEvent */
var ripples = { var ripples = {
init : function(withRipple) { init : function(withRipple) {
"use strict"; "use strict";
// Helper to bind events on dynamically created elements // animations time
var bind = function(event, selector, callback) { var rippleOutTime = 100,
document.addEventListener(event, function(e) { rippleStartTime = 500;
var target = (typeof e.detail !== "number") ? e.detail : e.target;
if (target.matches(selector)) { // Helper to bind events on dynamically created elements
callback(e, target); var bind = function(event, selector, callback) {
} document.addEventListener(event, function(e) {
}); var target = (typeof e.detail !== "number") ? e.detail : e.target;
};
var rippleStart = function(e, target) { if (target.matches(selector)) {
callback(e, target);
}
});
};
// Init variables var rippleStart = function(e, target) {
var $rippleWrapper = (target.matches(".ripple-wrapper")) ? target : target.parentNode,
$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 // Init variables
$ripple.className = "ripple"; var $rippleWrapper = (target.matches(".ripple-wrapper")) ? target : target.parentNode,
$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;
// Move ripple to the mouse position // Set ripple class
$ripple.setAttribute("style", "left:" + mousePos.x + "px; top:" + mousePos.y + "px;"); $ripple.className = "ripple";
// Insert new ripple into ripple wrapper // Move ripple to the mouse position
$rippleWrapper.appendChild($ripple); $ripple.setAttribute("style", "left:" + mousePos.x + "px; top:" + mousePos.y + "px;");
// Make sure the ripple has the class applied (ugly hack but it works) // Insert new ripple into ripple wrapper
refreshElementStyle = window.getComputedStyle($ripple).opacity; $rippleWrapper.appendChild($ripple);
// Let other funtions know that this element is animating // Make sure the ripple has the class applied (ugly hack but it works)
$ripple.dataset.animating = 1; refreshElementStyle = window.getComputedStyle($ripple).opacity;
// Set scale value to ripple and animate it // Let other funtions know that this element is animating
$ripple.className = "ripple ripple-on"; $ripple.dataset.animating = 1;
$ripple.setAttribute("style", $ripple.getAttribute("style") + ["-ms-" + scale,"-moz-" + scale,"-webkit-" + scale,scale].join(";"));
// This function is called when the animation is finished // Set scale value to ripple and animate it
setTimeout(function() { $ripple.className = "ripple ripple-on";
$ripple.setAttribute("style", $ripple.getAttribute("style") + ["-ms-" + scale,"-moz-" + scale,"-webkit-" + scale,scale].join(";"));
// Let know to other functions that this element has finished the animation // This function is called when the animation is finished
$ripple.dataset.animating = 0; setTimeout(function() {
document.dispatchEvent(rippleEnd);
}, 500); // 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) var rippleOut = function($ripple) {
setTimeout(function() { // Clear previous animation
$ripple.remove(); $ripple.className = "ripple ripple-on ripple-out";
}, 1000);
};
// Helper, need to know if mouse is up or down // Let ripple fade out (with CSS)
var mouseDown = false; setTimeout(function() {
document.body.onmousedown = function() { $ripple.remove();
mouseDown = true; }, rippleOutTime);
}; };
document.body.onmouseup = function() {
mouseDown = false;
};
// Append ripple wrapper if not exists already // Helper, need to know if mouse is up or down
var rippleInit = function(e, target) { var mouseDown = false;
document.body.onmousedown = function() {
mouseDown = true;
};
document.body.onmouseup = function() {
mouseDown = false;
};
if (target.getElementsByClassName("ripple-wrapper").length === 0) { // Append ripple wrapper if not exists already
target.className += " withripple"; var rippleInit = function(e, target) {
var $rippleWrapper = document.createElement("div");
$rippleWrapper.className = "ripple-wrapper";
target.appendChild($rippleWrapper);
rippleStart(e, $rippleWrapper);
}
}; 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);
// start ripple effect on mousedown
bind("mousedown", ".ripple-wrapper, .ripple", rippleStart);
// if animation ends and user is not holding mouse then destroy the ripple
bind("rippleEnd", ".ripple-wrapper, .ripple", function(e, $ripple) {
if (!mouseDown) {
rippleOut($ripple);
}
});
// Destroy ripple when mouse is not holded anymore if the ripple still exists
bind("mouseup", ".ripple-wrapper, .ripple", function(e, $ripple) {
if ($ripple.dataset.animating != 1) {
rippleOut($ripple);
}
});
} // Events handler
// init RippleJS and start ripple effect on mousedown
bind("mousedown", withRipple, rippleInit);
// start ripple effect on mousedown
bind("mousedown", ".ripple-wrapper, .ripple", rippleStart);
// if animation ends and user is not holding mouse then destroy the ripple
bind("rippleEnd", ".ripple-wrapper, .ripple", function(e, $ripple) {
if (!mouseDown) {
rippleOut($ripple);
}
});
// Destroy ripple when mouse is not holded anymore if the ripple still exists
bind("mouseup", ".ripple-wrapper, .ripple", function(e, $ripple) {
if ($ripple.dataset.animating != 1) {
rippleOut($ripple);
}
});
}
}; };