Index: lib/src/paper-ripple/paper-ripple.html |
diff --git a/lib/src/paper-ripple/paper-ripple.html b/lib/src/paper-ripple/paper-ripple.html |
index 2c8e4fb42658ed493bd9f77b58a919c238bd5a13..6c0b79bef61d63d9b292a3bff1e7786221c10786 100644 |
--- a/lib/src/paper-ripple/paper-ripple.html |
+++ b/lib/src/paper-ripple/paper-ripple.html |
@@ -11,19 +11,26 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN |
<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> |
<!-- |
+Material design: [Surface reaction](https://www.google.com/design/spec/animation/responsive-interaction.html#responsive-interaction-surface-reaction) |
+ |
`paper-ripple` provides a visual effect that other paper elements can |
use to simulate a rippling effect emanating from the point of contact. The |
effect can be visualized as a concentric circle with motion. |
Example: |
- <paper-ripple></paper-ripple> |
+ <div style="position:relative"> |
+ <paper-ripple></paper-ripple> |
+ </div> |
+ |
+Note, it's important that the parent container of the ripple be relative position, otherwise |
+the ripple will emanate outside of the desired container. |
`paper-ripple` listens to "mousedown" and "mouseup" events so it would display ripple |
effect when touches on it. You can also defeat the default behavior and |
manually route the down and up actions to the ripple element. Note that it is |
-important if you call downAction() you will have to make sure to call |
-upAction() so that `paper-ripple` would end the animation loop. |
+important if you call `downAction()` you will have to make sure to call |
+`upAction()` so that `paper-ripple` would end the animation loop. |
Example: |
@@ -76,7 +83,7 @@ Apply `circle` class to make the rippling effect within a circle. |
@param {Object} detail |
@param {Object} detail.node The animated node |
--> |
- |
+ |
<template> |
<style> |
:host { |
@@ -88,24 +95,30 @@ Apply `circle` class to make the rippling effect within a circle. |
left: 0; |
right: 0; |
bottom: 0; |
+ |
+ /* See PolymerElements/paper-behaviors/issues/34. On non-Chrome browsers, |
+ * creating a node (with a position:absolute) in the middle of an event |
+ * handler "interrupts" that event handler (which happens when the |
+ * ripple is created on demand) */ |
+ pointer-events: none; |
} |
- |
+ |
:host([animating]) { |
/* This resolves a rendering issue in Chrome (as of 40) where the |
ripple is not properly clipped by its parent (which may have |
rounded corners). See: http://jsbin.com/temexa/4 |
- |
+ |
Note: We only apply this style conditionally. Otherwise, the browser |
will create a new compositing layer for every ripple element on the |
page, and that would be bad. */ |
-webkit-transform: translate(0, 0); |
transform: translate3d(0, 0, 0); |
} |
- |
+ |
:host([noink]) { |
pointer-events: none; |
} |
- |
+ |
#background, |
#waves, |
.wave-container, |
@@ -117,32 +130,32 @@ Apply `circle` class to make the rippling effect within a circle. |
width: 100%; |
height: 100%; |
} |
- |
+ |
#background, |
.wave { |
opacity: 0; |
} |
- |
+ |
#waves, |
.wave { |
overflow: hidden; |
} |
- |
+ |
.wave-container, |
.wave { |
border-radius: 50%; |
} |
- |
+ |
:host(.circle) #background, |
:host(.circle) #waves { |
border-radius: 50%; |
} |
- |
+ |
:host(.circle) .wave-container { |
overflow: hidden; |
} |
</style> |
- |
+ |
<div id="background"></div> |
<div id="waves"></div> |
</template> |
@@ -526,6 +539,17 @@ Apply `circle` class to make the rippling effect within a circle. |
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 |
}, |
@@ -538,6 +562,10 @@ Apply `circle` class to make the rippling effect within a circle. |
} |
}, |
+ observers: [ |
+ '_noinkChanged(noink, isAttached)' |
+ ], |
+ |
get target () { |
var ownerRoot = Polymer.dom(this).getOwnerRoot(); |
var target; |
@@ -558,12 +586,13 @@ Apply `circle` class to make the rippling effect within a circle. |
}, |
attached: function() { |
- this.listen(this.target, 'up', 'upAction'); |
- this.listen(this.target, 'down', 'downAction'); |
+ this.listen(this.target, 'up', 'uiUpAction'); |
+ this.listen(this.target, 'down', 'uiDownAction'); |
+ }, |
- if (!this.target.hasAttribute('noink')) { |
- this.keyEventTarget = this.target; |
- } |
+ detached: function() { |
+ this.unlisten(this.target, 'up', 'uiUpAction'); |
+ this.unlisten(this.target, 'down', 'uiDownAction'); |
}, |
get shouldKeepAnimating () { |
@@ -585,7 +614,22 @@ Apply `circle` class to make the rippling effect within a circle. |
}, 1); |
}, |
- /** @param {Event=} event */ |
+ /** |
+ * 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; |
@@ -600,7 +644,22 @@ Apply `circle` class to make the rippling effect within a circle. |
} |
}, |
- /** @param {Event=} event */ |
+ /** |
+ * 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; |
@@ -673,24 +732,35 @@ Apply `circle` class to make the rippling effect within a circle. |
}, |
_onEnterKeydown: function() { |
- this.downAction(); |
- this.async(this.upAction, 1); |
+ this.uiDownAction(); |
+ this.async(this.uiUpAction, 1); |
}, |
_onSpaceKeydown: function() { |
- this.downAction(); |
+ this.uiDownAction(); |
}, |
_onSpaceKeyup: function() { |
- this.upAction(); |
+ this.uiUpAction(); |
}, |
- _holdDownChanged: function(holdDown) { |
- if (holdDown) { |
+ // 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(); |
} |
+ }, |
+ |
+ _noinkChanged: function(noink, attached) { |
+ if (attached) { |
+ this.keyEventTarget = noink ? this : this.target; |
+ } |
} |
}); |
})(); |