Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: bower_components/paper-ripple/paper-ripple.html

Issue 786953007: npm_modules: Fork bower_components into Polymer 0.4.0 and 0.5.0 versions (Closed) Base URL: https://chromium.googlesource.com/infra/third_party/npm_modules.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « bower_components/paper-ripple/metadata.html ('k') | bower_components/paper-ripple/raw.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 <!--
2 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3 This code may only be used under the BSD style license found at http://polymer.g ithub.io/LICENSE.txt
4 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
5 The complete set of contributors may be found at http://polymer.github.io/CONTRI BUTORS.txt
6 Code distributed by Google as part of the polymer project is also
7 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS.txt
8 -->
9
10 <!--
11 `paper-ripple` provides a visual effect that other paper elements can
12 use to simulate a rippling effect emanating from the point of contact. The
13 effect can be visualized as a concentric circle with motion.
14
15 Example:
16
17 <paper-ripple></paper-ripple>
18
19 `paper-ripple` listens to "down" and "up" events so it would display ripple
20 effect when touches on it. You can also defeat the default behavior and
21 manually route the down and up actions to the ripple element. Note that it is
22 important if you call downAction() you will have to make sure to call upAction()
23 so that `paper-ripple` would end the animation loop.
24
25 Example:
26
27 <paper-ripple id="ripple" style="pointer-events: none;"></paper-ripple>
28 ...
29 downAction: function(e) {
30 this.$.ripple.downAction({x: e.x, y: e.y});
31 },
32 upAction: function(e) {
33 this.$.ripple.upAction();
34 }
35
36 Styling ripple effect:
37
38 Use CSS color property to style the ripple:
39
40 paper-ripple {
41 color: #4285f4;
42 }
43
44 Note that CSS color property is inherited so it is not required to set it on
45 the `paper-ripple` element directly.
46
47 Apply `recenteringTouch` class to make the recentering rippling effect.
48
49 <paper-ripple class="recenteringTouch"></paper-ripple>
50
51 Apply `circle` class to make the rippling effect within a circle.
52
53 <paper-ripple class="circle"></paper-ripple>
54
55 @group Paper Elements
56 @element paper-ripple
57 @homepage github.io
58 -->
59
60 <link rel="import" href="../polymer/polymer.html" >
61
62 <polymer-element name="paper-ripple" attributes="initialOpacity opacityDecayVelo city">
63 <template>
64
65 <style>
66
67 :host {
68 display: block;
69 position: relative;
70 border-radius: inherit;
71 overflow: hidden;
72 }
73
74 :host-context([noink]) {
75 pointer-events: none;
76 }
77
78 #bg, #waves, .wave-container, .wave {
79 pointer-events: none;
80 position: absolute;
81 top: 0;
82 left: 0;
83 width: 100%;
84 height: 100%;
85 }
86
87 #bg, .wave {
88 opacity: 0;
89 }
90
91 #waves, .wave {
92 overflow: hidden;
93 }
94
95 .wave-container, .wave {
96 border-radius: 50%;
97 }
98
99 :host(.circle) #bg,
100 :host(.circle) #waves {
101 border-radius: 50%;
102 }
103
104 :host(.circle) .wave-container {
105 overflow: hidden;
106 }
107
108 </style>
109
110 <div id="bg"></div>
111 <div id="waves">
112 </div>
113
114 </template>
115 <script>
116
117 (function() {
118
119 var waveMaxRadius = 150;
120 //
121 // INK EQUATIONS
122 //
123 function waveRadiusFn(touchDownMs, touchUpMs, anim) {
124 // Convert from ms to s.
125 var touchDown = touchDownMs / 1000;
126 var touchUp = touchUpMs / 1000;
127 var totalElapsed = touchDown + touchUp;
128 var ww = anim.width, hh = anim.height;
129 // use diagonal size of container to avoid floating point math sadness
130 var waveRadius = Math.min(Math.sqrt(ww * ww + hh * hh), waveMaxRadius) * 1 .1 + 5;
131 var duration = 1.1 - .2 * (waveRadius / waveMaxRadius);
132 var tt = (totalElapsed / duration);
133
134 var size = waveRadius * (1 - Math.pow(80, -tt));
135 return Math.abs(size);
136 }
137
138 function waveOpacityFn(td, tu, anim) {
139 // Convert from ms to s.
140 var touchDown = td / 1000;
141 var touchUp = tu / 1000;
142 var totalElapsed = touchDown + touchUp;
143
144 if (tu <= 0) { // before touch up
145 return anim.initialOpacity;
146 }
147 return Math.max(0, anim.initialOpacity - touchUp * anim.opacityDecayVeloci ty);
148 }
149
150 function waveOuterOpacityFn(td, tu, anim) {
151 // Convert from ms to s.
152 var touchDown = td / 1000;
153 var touchUp = tu / 1000;
154
155 // Linear increase in background opacity, capped at the opacity
156 // of the wavefront (waveOpacity).
157 var outerOpacity = touchDown * 0.3;
158 var waveOpacity = waveOpacityFn(td, tu, anim);
159 return Math.max(0, Math.min(outerOpacity, waveOpacity));
160 }
161
162 // Determines whether the wave should be completely removed.
163 function waveDidFinish(wave, radius, anim) {
164 var waveOpacity = waveOpacityFn(wave.tDown, wave.tUp, anim);
165
166 // If the wave opacity is 0 and the radius exceeds the bounds
167 // of the element, then this is finished.
168 return waveOpacity < 0.01 && radius >= Math.min(wave.maxRadius, waveMaxRad ius);
169 };
170
171 function waveAtMaximum(wave, radius, anim) {
172 var waveOpacity = waveOpacityFn(wave.tDown, wave.tUp, anim);
173
174 return waveOpacity >= anim.initialOpacity && radius >= Math.min(wave.maxRa dius, waveMaxRadius);
175 }
176
177 //
178 // DRAWING
179 //
180 function drawRipple(ctx, x, y, radius, innerAlpha, outerAlpha) {
181 // Only animate opacity and transform
182 if (outerAlpha !== undefined) {
183 ctx.bg.style.opacity = outerAlpha;
184 }
185 ctx.wave.style.opacity = innerAlpha;
186
187 var s = radius / (ctx.containerSize / 2);
188 var dx = x - (ctx.containerWidth / 2);
189 var dy = y - (ctx.containerHeight / 2);
190
191 ctx.wc.style.webkitTransform = 'translate3d(' + dx + 'px,' + dy + 'px,0)';
192 ctx.wc.style.transform = 'translate3d(' + dx + 'px,' + dy + 'px,0)';
193
194 // 2d transform for safari because of border-radius and overflow:hidden cl ipping bug.
195 // https://bugs.webkit.org/show_bug.cgi?id=98538
196 ctx.wave.style.webkitTransform = 'scale(' + s + ',' + s + ')';
197 ctx.wave.style.transform = 'scale3d(' + s + ',' + s + ',1)';
198 }
199
200 //
201 // SETUP
202 //
203 function createWave(elem) {
204 var elementStyle = window.getComputedStyle(elem);
205 var fgColor = elementStyle.color;
206
207 var inner = document.createElement('div');
208 inner.style.backgroundColor = fgColor;
209 inner.classList.add('wave');
210
211 var outer = document.createElement('div');
212 outer.classList.add('wave-container');
213 outer.appendChild(inner);
214
215 var container = elem.$.waves;
216 container.appendChild(outer);
217
218 elem.$.bg.style.backgroundColor = fgColor;
219
220 var wave = {
221 bg: elem.$.bg,
222 wc: outer,
223 wave: inner,
224 waveColor: fgColor,
225 maxRadius: 0,
226 isMouseDown: false,
227 mouseDownStart: 0.0,
228 mouseUpStart: 0.0,
229 tDown: 0,
230 tUp: 0
231 };
232 return wave;
233 }
234
235 function removeWaveFromScope(scope, wave) {
236 if (scope.waves) {
237 var pos = scope.waves.indexOf(wave);
238 scope.waves.splice(pos, 1);
239 // FIXME cache nodes
240 wave.wc.remove();
241 }
242 };
243
244 // Shortcuts.
245 var pow = Math.pow;
246 var now = Date.now;
247 if (window.performance && performance.now) {
248 now = performance.now.bind(performance);
249 }
250
251 function cssColorWithAlpha(cssColor, alpha) {
252 var parts = cssColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
253 if (typeof alpha == 'undefined') {
254 alpha = 1;
255 }
256 if (!parts) {
257 return 'rgba(255, 255, 255, ' + alpha + ')';
258 }
259 return 'rgba(' + parts[1] + ', ' + parts[2] + ', ' + parts[3] + ', ' + a lpha + ')';
260 }
261
262 function dist(p1, p2) {
263 return Math.sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2));
264 }
265
266 function distanceFromPointToFurthestCorner(point, size) {
267 var tl_d = dist(point, {x: 0, y: 0});
268 var tr_d = dist(point, {x: size.w, y: 0});
269 var bl_d = dist(point, {x: 0, y: size.h});
270 var br_d = dist(point, {x: size.w, y: size.h});
271 return Math.max(tl_d, tr_d, bl_d, br_d);
272 }
273
274 Polymer('paper-ripple', {
275
276 /**
277 * The initial opacity set on the wave.
278 *
279 * @attribute initialOpacity
280 * @type number
281 * @default 0.25
282 */
283 initialOpacity: 0.25,
284
285 /**
286 * How fast (opacity per second) the wave fades out.
287 *
288 * @attribute opacityDecayVelocity
289 * @type number
290 * @default 0.8
291 */
292 opacityDecayVelocity: 0.8,
293
294 backgroundFill: true,
295 pixelDensity: 2,
296
297 eventDelegates: {
298 down: 'downAction',
299 up: 'upAction'
300 },
301
302 ready: function() {
303 this.waves = [];
304 },
305
306 downAction: function(e) {
307 var wave = createWave(this);
308
309 this.cancelled = false;
310 wave.isMouseDown = true;
311 wave.tDown = 0.0;
312 wave.tUp = 0.0;
313 wave.mouseUpStart = 0.0;
314 wave.mouseDownStart = now();
315
316 var rect = this.getBoundingClientRect();
317 var width = rect.width;
318 var height = rect.height;
319 var touchX = e.x - rect.left;
320 var touchY = e.y - rect.top;
321
322 wave.startPosition = {x:touchX, y:touchY};
323
324 if (this.classList.contains("recenteringTouch")) {
325 wave.endPosition = {x: width / 2, y: height / 2};
326 wave.slideDistance = dist(wave.startPosition, wave.endPosition);
327 }
328 wave.containerSize = Math.max(width, height);
329 wave.containerWidth = width;
330 wave.containerHeight = height;
331 wave.maxRadius = distanceFromPointToFurthestCorner(wave.startPosition, { w: width, h: height});
332
333 // The wave is circular so constrain its container to 1:1
334 wave.wc.style.top = (wave.containerHeight - wave.containerSize) / 2 + 'p x';
335 wave.wc.style.left = (wave.containerWidth - wave.containerSize) / 2 + 'p x';
336 wave.wc.style.width = wave.containerSize + 'px';
337 wave.wc.style.height = wave.containerSize + 'px';
338
339 this.waves.push(wave);
340
341 if (!this._loop) {
342 this._loop = this.animate.bind(this, {
343 width: width,
344 height: height
345 });
346 requestAnimationFrame(this._loop);
347 }
348 // else there is already a rAF
349 },
350
351 upAction: function() {
352 for (var i = 0; i < this.waves.length; i++) {
353 // Declare the next wave that has mouse down to be mouse'ed up.
354 var wave = this.waves[i];
355 if (wave.isMouseDown) {
356 wave.isMouseDown = false
357 wave.mouseUpStart = now();
358 wave.mouseDownStart = 0;
359 wave.tUp = 0.0;
360 break;
361 }
362 }
363 this._loop && requestAnimationFrame(this._loop);
364 },
365
366 cancel: function() {
367 this.cancelled = true;
368 },
369
370 animate: function(ctx) {
371 var shouldRenderNextFrame = false;
372
373 var deleteTheseWaves = [];
374 // The oldest wave's touch down duration
375 var longestTouchDownDuration = 0;
376 var longestTouchUpDuration = 0;
377 // Save the last known wave color
378 var lastWaveColor = null;
379 // wave animation values
380 var anim = {
381 initialOpacity: this.initialOpacity,
382 opacityDecayVelocity: this.opacityDecayVelocity,
383 height: ctx.height,
384 width: ctx.width
385 }
386
387 for (var i = 0; i < this.waves.length; i++) {
388 var wave = this.waves[i];
389
390 if (wave.mouseDownStart > 0) {
391 wave.tDown = now() - wave.mouseDownStart;
392 }
393 if (wave.mouseUpStart > 0) {
394 wave.tUp = now() - wave.mouseUpStart;
395 }
396
397 // Determine how long the touch has been up or down.
398 var tUp = wave.tUp;
399 var tDown = wave.tDown;
400 longestTouchDownDuration = Math.max(longestTouchDownDuration, tDown);
401 longestTouchUpDuration = Math.max(longestTouchUpDuration, tUp);
402
403 // Obtain the instantenous size and alpha of the ripple.
404 var radius = waveRadiusFn(tDown, tUp, anim);
405 var waveAlpha = waveOpacityFn(tDown, tUp, anim);
406 var waveColor = cssColorWithAlpha(wave.waveColor, waveAlpha);
407 lastWaveColor = wave.waveColor;
408
409 // Position of the ripple.
410 var x = wave.startPosition.x;
411 var y = wave.startPosition.y;
412
413 // Ripple gravitational pull to the center of the canvas.
414 if (wave.endPosition) {
415
416 // This translates from the origin to the center of the view based on the max dimension of
417 var translateFraction = Math.min(1, radius / wave.containerSize * 2 / Math.sqrt(2) );
418
419 x += translateFraction * (wave.endPosition.x - wave.startPosition.x) ;
420 y += translateFraction * (wave.endPosition.y - wave.startPosition.y) ;
421 }
422
423 // If we do a background fill fade too, work out the correct color.
424 var bgFillColor = null;
425 if (this.backgroundFill) {
426 var bgFillAlpha = waveOuterOpacityFn(tDown, tUp, anim);
427 bgFillColor = cssColorWithAlpha(wave.waveColor, bgFillAlpha);
428 }
429
430 // Draw the ripple.
431 drawRipple(wave, x, y, radius, waveAlpha, bgFillAlpha);
432
433 // Determine whether there is any more rendering to be done.
434 var maximumWave = waveAtMaximum(wave, radius, anim);
435 var waveDissipated = waveDidFinish(wave, radius, anim);
436 var shouldKeepWave = !waveDissipated || maximumWave;
437 // keep rendering dissipating wave when at maximum radius on upAction
438 var shouldRenderWaveAgain = wave.mouseUpStart ? !waveDissipated : !max imumWave;
439 shouldRenderNextFrame = shouldRenderNextFrame || shouldRenderWaveAgain ;
440 if (!shouldKeepWave || this.cancelled) {
441 deleteTheseWaves.push(wave);
442 }
443 }
444
445 if (shouldRenderNextFrame) {
446 requestAnimationFrame(this._loop);
447 }
448
449 for (var i = 0; i < deleteTheseWaves.length; ++i) {
450 var wave = deleteTheseWaves[i];
451 removeWaveFromScope(this, wave);
452 }
453
454 if (!this.waves.length && this._loop) {
455 // clear the background color
456 this.$.bg.style.backgroundColor = null;
457 this._loop = null;
458 this.fire('core-transitionend');
459 }
460 }
461
462 });
463
464 })();
465
466 </script>
467 </polymer-element>
OLDNEW
« no previous file with comments | « bower_components/paper-ripple/metadata.html ('k') | bower_components/paper-ripple/raw.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698