| Index: third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js
|
| diff --git a/third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js b/third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js
|
| index d4c41ad0f92ebf48eec311e6c4a24c2115d17c53..d57ca91698fe86c428e9456450bcb2b4d236de1c 100644
|
| --- a/third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js
|
| +++ b/third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js
|
| @@ -1,611 +1,207 @@
|
| (function() {
|
| - var Utility = {
|
| - distance: function(x1, y1, x2, y2) {
|
| - var xDelta = (x1 - x2);
|
| - var yDelta = (y1 - y2);
|
|
|
| - return Math.sqrt(xDelta * xDelta + yDelta * yDelta);
|
| - },
|
| -
|
| - now: window.performance && window.performance.now ?
|
| - window.performance.now.bind(window.performance) : Date.now
|
| - };
|
| -
|
| - /**
|
| - * @param {HTMLElement} element
|
| - * @constructor
|
| - */
|
| - function ElementMetrics(element) {
|
| - this.element = element;
|
| - this.width = this.boundingRect.width;
|
| - this.height = this.boundingRect.height;
|
| -
|
| - this.size = Math.max(this.width, this.height);
|
| +var MAX_RADIUS_PX = 300;
|
| +var MIN_DURATION_MS = 800;
|
| +
|
| +/**
|
| + * @param {number} x1
|
| + * @param {number} y1
|
| + * @param {number} x2
|
| + * @param {number} y2
|
| + * @return {number} The distance between (x1, y1) and (x2, y2).
|
| + */
|
| +var distance = function(x1, y1, x2, y2) {
|
| + var xDelta = x1 - x2;
|
| + var yDelta = y1 - y2;
|
| + return Math.sqrt(xDelta * xDelta + yDelta * yDelta);
|
| +};
|
| +
|
| +Polymer({
|
| + is: 'paper-ripple',
|
| +
|
| + behaviors: [Polymer.IronA11yKeysBehavior],
|
| +
|
| + properties: {
|
| + center: {type: Boolean, value: false},
|
| + holdDown: {type: Boolean, value: false, observer: '_holdDownChanged'},
|
| + recenters: {type: Boolean, value: false},
|
| + noink: {type: Boolean, value: false},
|
| + },
|
| +
|
| + keyBindings: {
|
| + 'enter:keydown': '_onEnterKeydown',
|
| + 'space:keydown': '_onSpaceKeydown',
|
| + 'space:keyup': '_onSpaceKeyup',
|
| + },
|
| +
|
| + /** @override */
|
| + created: function() {
|
| + /** @type {Array<!Element>} */
|
| + this.ripples = [];
|
| + },
|
| +
|
| + /** @override */
|
| + attached: function() {
|
| + this.keyEventTarget = this.parentNode.nodeType == 11 ?
|
| + Polymer.dom(this).getOwnerRoot().host : this.parentNode;
|
| + this.keyEventTarget = /** @type {!EventTarget} */ (this.keyEventTarget);
|
| + this.listen(this.keyEventTarget, 'up', 'uiUpAction');
|
| + this.listen(this.keyEventTarget, 'down', 'uiDownAction');
|
| + },
|
| +
|
| + /** @override */
|
| + detached: function() {
|
| + this.unlisten(this.keyEventTarget, 'up', 'uiUpAction');
|
| + this.unlisten(this.keyEventTarget, 'down', 'uiDownAction');
|
| + this.keyEventTarget = null;
|
| + },
|
| +
|
| + simulatedRipple: function() {
|
| + this.downAction();
|
| + // Using a 1ms delay ensures a macro-task.
|
| + this.async(function() { this.upAction(); }.bind(this), 1);
|
| + },
|
| +
|
| + /** @param {Event=} e */
|
| + uiDownAction: function(e) {
|
| + if (!this.noink)
|
| + this.downAction(e);
|
| + },
|
| +
|
| + /** @param {Event=} e */
|
| + downAction: function(e) {
|
| + if (this.ripples.length && this.holdDown)
|
| + return;
|
| + // TODO(dbeam): some things (i.e. paper-icon-button-light) dynamically
|
| + // create ripples on 'up', Ripples register an event listener on their
|
| + // parent (or shadow DOM host) when attached(). This sometimes causes
|
| + // duplicate events to fire on us.
|
| + this.debounce('show ripple', function() { this.__showRipple(e); }, 1);
|
| + },
|
| +
|
| + /**
|
| + * @param {Event=} e
|
| + * @private
|
| + * @suppress {checkTypes}
|
| + */
|
| + __showRipple: function(e) {
|
| + var rect = this.getBoundingClientRect();
|
| +
|
| + var roundedCenterX = function() { return Math.round(rect.width / 2); };
|
| + var roundedCenterY = function() { return Math.round(rect.height / 2); };
|
| +
|
| + var centered = !e || this.center;
|
| + if (centered) {
|
| + var x = roundedCenterX();
|
| + var y = roundedCenterY();
|
| + } else {
|
| + var sourceEvent = e.detail.sourceEvent;
|
| + var x = Math.round(sourceEvent.clientX - rect.left);
|
| + var y = Math.round(sourceEvent.clientY - rect.top);
|
| }
|
|
|
| - ElementMetrics.prototype = {
|
| - get boundingRect () {
|
| - return this.element.getBoundingClientRect();
|
| - },
|
| -
|
| - furthestCornerDistanceFrom: function(x, y) {
|
| - var topLeft = Utility.distance(x, y, 0, 0);
|
| - var topRight = Utility.distance(x, y, this.width, 0);
|
| - var bottomLeft = Utility.distance(x, y, 0, this.height);
|
| - var bottomRight = Utility.distance(x, y, this.width, this.height);
|
| + var corners = [
|
| + {x: 0, y: 0},
|
| + {x: rect.width, y: 0},
|
| + {x: 0, y: rect.height},
|
| + {x: rect.width, y: rect.height},
|
| + ];
|
|
|
| - return Math.max(topLeft, topRight, bottomLeft, bottomRight);
|
| - }
|
| - };
|
| -
|
| - /**
|
| - * @param {HTMLElement} element
|
| - * @constructor
|
| - */
|
| - function Ripple(element) {
|
| - this.element = element;
|
| - this.color = window.getComputedStyle(element).color;
|
| + var cornerDistances = corners.map(function(corner) {
|
| + return Math.round(distance(x, y, corner.x, corner.y));
|
| + });
|
|
|
| - this.wave = document.createElement('div');
|
| - this.waveContainer = document.createElement('div');
|
| - this.wave.style.backgroundColor = this.color;
|
| - this.wave.classList.add('wave');
|
| - this.waveContainer.classList.add('wave-container');
|
| - Polymer.dom(this.waveContainer).appendChild(this.wave);
|
| + var radius = Math.min(MAX_RADIUS_PX, Math.max.apply(Math, cornerDistances));
|
|
|
| - this.resetInteractionState();
|
| + var startTranslate = (x - radius) + 'px, ' + (y - radius) + 'px';
|
| + if (this.recenters && !centered) {
|
| + var endTranslate = (roundedCenterX() - radius) + 'px, ' +
|
| + (roundedCenterY() - radius) + 'px';
|
| + } else {
|
| + var endTranslate = startTranslate;
|
| }
|
|
|
| - Ripple.MAX_RADIUS = 300;
|
| -
|
| - Ripple.prototype = {
|
| - get recenters() {
|
| - return this.element.recenters;
|
| - },
|
| -
|
| - get center() {
|
| - return this.element.center;
|
| - },
|
| -
|
| - get mouseDownElapsed() {
|
| - var elapsed;
|
| -
|
| - if (!this.mouseDownStart) {
|
| - return 0;
|
| - }
|
| -
|
| - elapsed = Utility.now() - this.mouseDownStart;
|
| -
|
| - if (this.mouseUpStart) {
|
| - elapsed -= this.mouseUpElapsed;
|
| - }
|
| -
|
| - return elapsed;
|
| - },
|
| -
|
| - get mouseUpElapsed() {
|
| - return this.mouseUpStart ?
|
| - Utility.now () - this.mouseUpStart : 0;
|
| - },
|
| -
|
| - get mouseDownElapsedSeconds() {
|
| - return this.mouseDownElapsed / 1000;
|
| - },
|
| -
|
| - get mouseUpElapsedSeconds() {
|
| - return this.mouseUpElapsed / 1000;
|
| - },
|
| -
|
| - get mouseInteractionSeconds() {
|
| - return this.mouseDownElapsedSeconds + this.mouseUpElapsedSeconds;
|
| - },
|
| -
|
| - get initialOpacity() {
|
| - return this.element.initialOpacity;
|
| - },
|
| -
|
| - get opacityDecayVelocity() {
|
| - return this.element.opacityDecayVelocity;
|
| - },
|
| -
|
| - get radius() {
|
| - var width2 = this.containerMetrics.width * this.containerMetrics.width;
|
| - var height2 = this.containerMetrics.height * this.containerMetrics.height;
|
| - var waveRadius = Math.min(
|
| - Math.sqrt(width2 + height2),
|
| - Ripple.MAX_RADIUS
|
| - ) * 1.1 + 5;
|
| -
|
| - var duration = 1.1 - 0.2 * (waveRadius / Ripple.MAX_RADIUS);
|
| - var timeNow = this.mouseInteractionSeconds / duration;
|
| - var size = waveRadius * (1 - Math.pow(80, -timeNow));
|
| -
|
| - return Math.abs(size);
|
| - },
|
| -
|
| - get opacity() {
|
| - if (!this.mouseUpStart) {
|
| - return this.initialOpacity;
|
| - }
|
| -
|
| - return Math.max(
|
| - 0,
|
| - this.initialOpacity - this.mouseUpElapsedSeconds * this.opacityDecayVelocity
|
| - );
|
| - },
|
| -
|
| - get outerOpacity() {
|
| - // Linear increase in background opacity, capped at the opacity
|
| - // of the wavefront (waveOpacity).
|
| - var outerOpacity = this.mouseUpElapsedSeconds * 0.3;
|
| - var waveOpacity = this.opacity;
|
| -
|
| - return Math.max(
|
| - 0,
|
| - Math.min(outerOpacity, waveOpacity)
|
| - );
|
| - },
|
| -
|
| - get isOpacityFullyDecayed() {
|
| - return this.opacity < 0.01 &&
|
| - this.radius >= Math.min(this.maxRadius, Ripple.MAX_RADIUS);
|
| - },
|
| -
|
| - get isRestingAtMaxRadius() {
|
| - return this.opacity >= this.initialOpacity &&
|
| - this.radius >= Math.min(this.maxRadius, Ripple.MAX_RADIUS);
|
| - },
|
| -
|
| - get isAnimationComplete() {
|
| - return this.mouseUpStart ?
|
| - this.isOpacityFullyDecayed : this.isRestingAtMaxRadius;
|
| - },
|
| -
|
| - get translationFraction() {
|
| - return Math.min(
|
| - 1,
|
| - this.radius / this.containerMetrics.size * 2 / Math.sqrt(2)
|
| - );
|
| - },
|
| -
|
| - get xNow() {
|
| - if (this.xEnd) {
|
| - return this.xStart + this.translationFraction * (this.xEnd - this.xStart);
|
| - }
|
| -
|
| - return this.xStart;
|
| - },
|
| -
|
| - get yNow() {
|
| - if (this.yEnd) {
|
| - return this.yStart + this.translationFraction * (this.yEnd - this.yStart);
|
| - }
|
| -
|
| - return this.yStart;
|
| - },
|
| -
|
| - get isMouseDown() {
|
| - return this.mouseDownStart && !this.mouseUpStart;
|
| - },
|
| -
|
| - resetInteractionState: function() {
|
| - this.maxRadius = 0;
|
| - this.mouseDownStart = 0;
|
| - this.mouseUpStart = 0;
|
| -
|
| - this.xStart = 0;
|
| - this.yStart = 0;
|
| - this.xEnd = 0;
|
| - this.yEnd = 0;
|
| - this.slideDistance = 0;
|
| -
|
| - this.containerMetrics = new ElementMetrics(this.element);
|
| - },
|
| -
|
| - draw: function() {
|
| - var scale;
|
| - var translateString;
|
| - var dx;
|
| - var dy;
|
| -
|
| - this.wave.style.opacity = this.opacity;
|
| -
|
| - scale = this.radius / (this.containerMetrics.size / 2);
|
| - dx = this.xNow - (this.containerMetrics.width / 2);
|
| - dy = this.yNow - (this.containerMetrics.height / 2);
|
| -
|
| -
|
| - // 2d transform for safari because of border-radius and overflow:hidden clipping bug.
|
| - // https://bugs.webkit.org/show_bug.cgi?id=98538
|
| - this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy + 'px)';
|
| - this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + 'px, 0)';
|
| - this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')';
|
| - this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)';
|
| - },
|
| -
|
| - /** @param {Event=} event */
|
| - downAction: function(event) {
|
| - var xCenter = this.containerMetrics.width / 2;
|
| - var yCenter = this.containerMetrics.height / 2;
|
| -
|
| - this.resetInteractionState();
|
| - this.mouseDownStart = Utility.now();
|
| -
|
| - if (this.center) {
|
| - this.xStart = xCenter;
|
| - this.yStart = yCenter;
|
| - this.slideDistance = Utility.distance(
|
| - this.xStart, this.yStart, this.xEnd, this.yEnd
|
| - );
|
| - } else {
|
| - this.xStart = event ?
|
| - event.detail.x - this.containerMetrics.boundingRect.left :
|
| - this.containerMetrics.width / 2;
|
| - this.yStart = event ?
|
| - event.detail.y - this.containerMetrics.boundingRect.top :
|
| - this.containerMetrics.height / 2;
|
| - }
|
| -
|
| - if (this.recenters) {
|
| - this.xEnd = xCenter;
|
| - this.yEnd = yCenter;
|
| - this.slideDistance = Utility.distance(
|
| - this.xStart, this.yStart, this.xEnd, this.yEnd
|
| - );
|
| - }
|
| -
|
| - this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom(
|
| - this.xStart,
|
| - this.yStart
|
| - );
|
| -
|
| - this.waveContainer.style.top =
|
| - (this.containerMetrics.height - this.containerMetrics.size) / 2 + 'px';
|
| - this.waveContainer.style.left =
|
| - (this.containerMetrics.width - this.containerMetrics.size) / 2 + 'px';
|
| -
|
| - this.waveContainer.style.width = this.containerMetrics.size + 'px';
|
| - this.waveContainer.style.height = this.containerMetrics.size + 'px';
|
| - },
|
| -
|
| - /** @param {Event=} event */
|
| - upAction: function(event) {
|
| - if (!this.isMouseDown) {
|
| - return;
|
| - }
|
| -
|
| - this.mouseUpStart = Utility.now();
|
| - },
|
| -
|
| - remove: function() {
|
| - Polymer.dom(this.waveContainer.parentNode).removeChild(
|
| - this.waveContainer
|
| - );
|
| - }
|
| - };
|
| -
|
| - Polymer({
|
| - is: 'paper-ripple',
|
| -
|
| - behaviors: [
|
| - Polymer.IronA11yKeysBehavior
|
| - ],
|
| -
|
| - properties: {
|
| - /**
|
| - * The initial opacity set on the wave.
|
| - *
|
| - * @attribute initialOpacity
|
| - * @type number
|
| - * @default 0.25
|
| - */
|
| - initialOpacity: {
|
| - type: Number,
|
| - value: 0.25
|
| - },
|
| -
|
| - /**
|
| - * How fast (opacity per second) the wave fades out.
|
| - *
|
| - * @attribute opacityDecayVelocity
|
| - * @type number
|
| - * @default 0.8
|
| - */
|
| - opacityDecayVelocity: {
|
| - type: Number,
|
| - value: 0.8
|
| - },
|
| -
|
| - /**
|
| - * If true, ripples will exhibit a gravitational pull towards
|
| - * the center of their container as they fade away.
|
| - *
|
| - * @attribute recenters
|
| - * @type boolean
|
| - * @default false
|
| - */
|
| - recenters: {
|
| - type: Boolean,
|
| - value: false
|
| - },
|
| -
|
| - /**
|
| - * If true, ripples will center inside its container
|
| - *
|
| - * @attribute recenters
|
| - * @type boolean
|
| - * @default false
|
| - */
|
| - center: {
|
| - type: Boolean,
|
| - value: false
|
| - },
|
| -
|
| - /**
|
| - * A list of the visual ripples.
|
| - *
|
| - * @attribute ripples
|
| - * @type Array
|
| - * @default []
|
| - */
|
| - ripples: {
|
| - type: Array,
|
| - value: function() {
|
| - return [];
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * True when there are visible ripples animating within the
|
| - * element.
|
| - */
|
| - animating: {
|
| - type: Boolean,
|
| - readOnly: true,
|
| - reflectToAttribute: true,
|
| - value: false
|
| - },
|
| -
|
| - /**
|
| - * If true, the ripple will remain in the "down" state until `holdDown`
|
| - * is set to false again.
|
| - */
|
| - holdDown: {
|
| - type: Boolean,
|
| - value: false,
|
| - observer: '_holdDownChanged'
|
| - },
|
| -
|
| - /**
|
| - * If true, the ripple will not generate a ripple effect
|
| - * via pointer interaction.
|
| - * Calling ripple's imperative api like `simulatedRipple` will
|
| - * still generate the ripple effect.
|
| - */
|
| - noink: {
|
| - type: Boolean,
|
| - value: false
|
| - },
|
| -
|
| - _animating: {
|
| - type: Boolean
|
| - },
|
| -
|
| - _boundAnimate: {
|
| - type: Function,
|
| - value: function() {
|
| - return this.animate.bind(this);
|
| - }
|
| - }
|
| - },
|
| -
|
| - get target () {
|
| - return this.keyEventTarget;
|
| - },
|
| -
|
| - keyBindings: {
|
| - 'enter:keydown': '_onEnterKeydown',
|
| - 'space:keydown': '_onSpaceKeydown',
|
| - 'space:keyup': '_onSpaceKeyup'
|
| - },
|
| -
|
| - attached: function() {
|
| - // Set up a11yKeysBehavior to listen to key events on the target,
|
| - // so that space and enter activate the ripple even if the target doesn't
|
| - // handle key events. The key handlers deal with `noink` themselves.
|
| - if (this.parentNode.nodeType == 11) { // DOCUMENT_FRAGMENT_NODE
|
| - this.keyEventTarget = Polymer.dom(this).getOwnerRoot().host;
|
| - } else {
|
| - this.keyEventTarget = this.parentNode;
|
| - }
|
| - var keyEventTarget = /** @type {!EventTarget} */ (this.keyEventTarget);
|
| - this.listen(keyEventTarget, 'up', 'uiUpAction');
|
| - this.listen(keyEventTarget, 'down', 'uiDownAction');
|
| - },
|
| -
|
| - detached: function() {
|
| - this.unlisten(this.keyEventTarget, 'up', 'uiUpAction');
|
| - this.unlisten(this.keyEventTarget, 'down', 'uiDownAction');
|
| - this.keyEventTarget = null;
|
| - },
|
| -
|
| - get shouldKeepAnimating () {
|
| - for (var index = 0; index < this.ripples.length; ++index) {
|
| - if (!this.ripples[index].isAnimationComplete) {
|
| - return true;
|
| - }
|
| - }
|
| -
|
| - return false;
|
| - },
|
| -
|
| - simulatedRipple: function() {
|
| - this.downAction(null);
|
| -
|
| - // Please see polymer/polymer#1305
|
| - this.async(function() {
|
| - this.upAction();
|
| - }, 1);
|
| - },
|
| -
|
| - /**
|
| - * Provokes a ripple down effect via a UI event,
|
| - * respecting the `noink` property.
|
| - * @param {Event=} event
|
| - */
|
| - uiDownAction: function(event) {
|
| - if (!this.noink) {
|
| - this.downAction(event);
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * Provokes a ripple down effect via a UI event,
|
| - * *not* respecting the `noink` property.
|
| - * @param {Event=} event
|
| - */
|
| - downAction: function(event) {
|
| - if (this.holdDown && this.ripples.length > 0) {
|
| - return;
|
| - }
|
| -
|
| - var ripple = this.addRipple();
|
| -
|
| - ripple.downAction(event);
|
| -
|
| - if (!this._animating) {
|
| - this._animating = true;
|
| - this.animate();
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * Provokes a ripple up effect via a UI event,
|
| - * respecting the `noink` property.
|
| - * @param {Event=} event
|
| - */
|
| - uiUpAction: function(event) {
|
| - if (!this.noink) {
|
| - this.upAction(event);
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * Provokes a ripple up effect via a UI event,
|
| - * *not* respecting the `noink` property.
|
| - * @param {Event=} event
|
| - */
|
| - upAction: function(event) {
|
| - if (this.holdDown) {
|
| - return;
|
| - }
|
| -
|
| - this.ripples.forEach(function(ripple) {
|
| - ripple.upAction(event);
|
| + var ripple = document.createElement('div');
|
| + ripple.classList.add('ripple');
|
| + ripple.style.height = ripple.style.width = (2 * radius) + 'px';
|
| +
|
| + this.ripples.push(ripple);
|
| + this.shadowRoot.appendChild(ripple);
|
| +
|
| + ripple.animate({
|
| + // TODO(dbeam): scale to 90% of radius at .75 offset?
|
| + transform: ['translate(' + startTranslate + ') scale(0)',
|
| + 'translate(' + endTranslate + ') scale(1)'],
|
| + }, {
|
| + duration: Math.max(MIN_DURATION_MS, Math.log(radius) * radius) || 0,
|
| + easing: 'cubic-bezier(.2, .9, .1, .9)',
|
| + fill: 'forwards',
|
| + });
|
| + },
|
| +
|
| + /** @param {Event=} e */
|
| + uiUpAction: function(e) {
|
| + if (!this.noink)
|
| + this.upAction();
|
| + },
|
| +
|
| + /** @param {Event=} e */
|
| + upAction: function(e) {
|
| + if (!this.holdDown)
|
| + this.debounce('hide ripple', function() { this.__hideRipple(); }, 1);
|
| + },
|
| +
|
| + /**
|
| + * @private
|
| + * @suppress {checkTypes}
|
| + */
|
| + __hideRipple: function() {
|
| + this.ripples.forEach(function(ripple) {
|
| + var removeRipple = function() { ripple.remove(); };
|
| + // TODO(dbeam): should we be firing a transitionend event here? Does
|
| + // anybody actually use it? It's in the original paper-ripple.
|
| + var opacity = getComputedStyle(ripple).opacity;
|
| + if (!opacity.length) {
|
| + removeRipple();
|
| + } else {
|
| + var animation = ripple.animate({
|
| + opacity: [opacity, 0],
|
| + }, {
|
| + duration: 150,
|
| + fill: 'forwards',
|
| });
|
| -
|
| - this._animating = true;
|
| - this.animate();
|
| - },
|
| -
|
| - onAnimationComplete: function() {
|
| - this._animating = false;
|
| - this.$.background.style.backgroundColor = null;
|
| - this.fire('transitionend');
|
| - },
|
| -
|
| - addRipple: function() {
|
| - var ripple = new Ripple(this);
|
| -
|
| - Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);
|
| - this.$.background.style.backgroundColor = ripple.color;
|
| - this.ripples.push(ripple);
|
| -
|
| - this._setAnimating(true);
|
| -
|
| - return ripple;
|
| - },
|
| -
|
| - removeRipple: function(ripple) {
|
| - var rippleIndex = this.ripples.indexOf(ripple);
|
| -
|
| - if (rippleIndex < 0) {
|
| - return;
|
| - }
|
| -
|
| - this.ripples.splice(rippleIndex, 1);
|
| -
|
| - ripple.remove();
|
| -
|
| - if (!this.ripples.length) {
|
| - this._setAnimating(false);
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * This conflicts with Element#antimate().
|
| - * https://developer.mozilla.org/en-US/docs/Web/API/Element/animate
|
| - * @suppress {checkTypes}
|
| - */
|
| - animate: function() {
|
| - if (!this._animating) {
|
| - return;
|
| - }
|
| - var index;
|
| - var ripple;
|
| -
|
| - for (index = 0; index < this.ripples.length; ++index) {
|
| - ripple = this.ripples[index];
|
| -
|
| - ripple.draw();
|
| -
|
| - this.$.background.style.opacity = ripple.outerOpacity;
|
| -
|
| - if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) {
|
| - this.removeRipple(ripple);
|
| - }
|
| - }
|
| -
|
| - if (!this.shouldKeepAnimating && this.ripples.length === 0) {
|
| - this.onAnimationComplete();
|
| - } else {
|
| - window.requestAnimationFrame(this._boundAnimate);
|
| - }
|
| - },
|
| -
|
| - _onEnterKeydown: function() {
|
| - this.uiDownAction();
|
| - this.async(this.uiUpAction, 1);
|
| - },
|
| -
|
| - _onSpaceKeydown: function() {
|
| - this.uiDownAction();
|
| - },
|
| -
|
| - _onSpaceKeyup: function() {
|
| - this.uiUpAction();
|
| - },
|
| -
|
| - // note: holdDown does not respect noink since it can be a focus based
|
| - // effect.
|
| - _holdDownChanged: function(newVal, oldVal) {
|
| - if (oldVal === undefined) {
|
| - return;
|
| - }
|
| - if (newVal) {
|
| - this.downAction();
|
| - } else {
|
| - this.upAction();
|
| - }
|
| + animation.addEventListener('finish', removeRipple);
|
| + animation.addEventListener('cancel', removeRipple);
|
| }
|
| -
|
| - /**
|
| - Fired when the animation finishes.
|
| - This is useful if you want to wait until
|
| - the ripple animation finishes to perform some action.
|
| -
|
| - @event transitionend
|
| - @param {{node: Object}} detail Contains the animated node.
|
| - */
|
| });
|
| - })();
|
| + this.ripples = [];
|
| + },
|
| +
|
| + /** @protected */
|
| + _onEnterKeydown: function() {
|
| + this.uiDownAction();
|
| + this.async(this.uiUpAction, 1);
|
| + },
|
| +
|
| + /** @protected */
|
| + _onSpaceKeydown: function() {
|
| + this.uiDownAction();
|
| + },
|
| +
|
| + /** @protected */
|
| + _onSpaceKeyup: function() {
|
| + this.uiUpAction();
|
| + },
|
| +
|
| + /** @protected */
|
| + _holdDownChanged: function(newHoldDown, oldHoldDown) {
|
| + if (oldHoldDown === undefined)
|
| + return;
|
| + if (newHoldDown)
|
| + this.downAction();
|
| + else
|
| + this.upAction();
|
| + },
|
| +});
|
| +
|
| +})();
|
|
|