blob: 04f2b17f712d03b93b62a6344558cd5b9a945506 [file] [log] [blame]
/* Copyright 2018 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
/**
* Contains common animations used in the main NTP page and its iframes.
*/
const animations = {};
/**
* Enum for classnames.
* @enum {string}
* @const
*/
animations.CLASSES = {
RIPPLE: 'ripple',
RIPPLE_CONTAINER: 'ripple-container',
RIPPLE_EFFECT_MASK: 'ripple-effect-mask',
RIPPLE_EFFECT: 'ripple-effect',
};
/**
* The duration of the ripple animation.
* @type {number}
* @const
*/
animations.RIPPLE_DURATION_MS = 800;
/**
* The max size of the ripple animation.
* @type {number}
* @const
*/
animations.RIPPLE_MAX_RADIUS_PX = 300;
/**
* Enables ripple animations for elements with CLASSES.RIPPLE. The target
* element must have position relative or absolute.
*/
animations.addRippleAnimations = function() {
const ripple = (event) => {
const target = event.target;
const rect = target.getBoundingClientRect();
const x = Math.round(event.clientX - rect.left);
const y = Math.round(event.clientY - rect.top);
// Calculate radius
const corners = [
{x: 0, y: 0},
{x: rect.width, y: 0},
{x: 0, y: rect.height},
{x: rect.width, y: rect.height},
];
const distance = (x1, y1, x2, y2) => {
const xDelta = x1 - x2;
const yDelta = y1 - y2;
return Math.sqrt(xDelta * xDelta + yDelta * yDelta);
};
const cornerDistances = corners.map(function(corner) {
return Math.round(distance(x, y, corner.x, corner.y));
});
const radius = Math.min(
animations.RIPPLE_MAX_RADIUS_PX, Math.max.apply(Math, cornerDistances));
const ripple = document.createElement('div');
const rippleMask = document.createElement('div');
const rippleContainer = document.createElement('div');
ripple.classList.add(animations.CLASSES.RIPPLE_EFFECT);
rippleMask.classList.add(animations.CLASSES.RIPPLE_EFFECT_MASK);
rippleContainer.classList.add(animations.CLASSES.RIPPLE_CONTAINER);
rippleMask.appendChild(ripple);
rippleContainer.appendChild(rippleMask);
target.appendChild(rippleContainer);
// Ripple start location
ripple.style.marginLeft = x + 'px';
ripple.style.marginTop = y + 'px';
rippleMask.style.width = target.offsetWidth + 'px';
rippleMask.style.height = target.offsetHeight + 'px';
rippleMask.style.borderRadius =
window.getComputedStyle(target).borderRadius;
// Start transition/ripple
ripple.style.width = radius * 2 + 'px';
ripple.style.height = radius * 2 + 'px';
ripple.style.marginLeft = x - radius + 'px';
ripple.style.marginTop = y - radius + 'px';
ripple.style.backgroundColor = 'rgba(0, 0, 0, 0)';
window.setTimeout(function() {
ripple.remove();
rippleMask.remove();
rippleContainer.remove();
}, animations.RIPPLE_DURATION_MS);
};
const rippleElements =
document.querySelectorAll('.' + animations.CLASSES.RIPPLE);
for (let i = 0; i < rippleElements.length; i++) {
rippleElements[i].addEventListener('mousedown', ripple);
}
};