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

Side by Side Diff: third_party/polymer/v1_0/components-chromium/paper-ripple/paper-ripple-extracted.js

Issue 1162963002: Revert "Rename polymer and cr_elements v0_8 to v1_0" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 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
OLDNEW
(Empty)
1
2 (function() {
3 var Utility = {
4 cssColorWithAlpha: function(cssColor, alpha) {
5 var parts = cssColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
6
7 if (typeof alpha == 'undefined') {
8 alpha = 1;
9 }
10
11 if (!parts) {
12 return 'rgba(255, 255, 255, ' + alpha + ')';
13 }
14
15 return 'rgba(' + parts[1] + ', ' + parts[2] + ', ' + parts[3] + ', ' + a lpha + ')';
16 },
17
18 distance: function(x1, y1, x2, y2) {
19 var xDelta = (x1 - x2);
20 var yDelta = (y1 - y2);
21
22 return Math.sqrt(xDelta * xDelta + yDelta * yDelta);
23 },
24
25 now: (function() {
26 if (window.performance && window.performance.now) {
27 return window.performance.now.bind(window.performance);
28 }
29
30 return Date.now;
31 })()
32 };
33
34 /**
35 * @param {HTMLElement} element
36 * @constructor
37 */
38 function ElementMetrics(element) {
39 this.element = element;
40 this.width = this.boundingRect.width;
41 this.height = this.boundingRect.height;
42
43 this.size = Math.max(this.width, this.height);
44 }
45
46 ElementMetrics.prototype = {
47 get boundingRect () {
48 return this.element.getBoundingClientRect();
49 },
50
51 furthestCornerDistanceFrom: function(x, y) {
52 var topLeft = Utility.distance(x, y, 0, 0);
53 var topRight = Utility.distance(x, y, this.width, 0);
54 var bottomLeft = Utility.distance(x, y, 0, this.height);
55 var bottomRight = Utility.distance(x, y, this.width, this.height);
56
57 return Math.max(topLeft, topRight, bottomLeft, bottomRight);
58 }
59 };
60
61 /**
62 * @param {HTMLElement} element
63 * @constructor
64 */
65 function Ripple(element) {
66 this.element = element;
67 this.color = window.getComputedStyle(element).color;
68
69 this.wave = document.createElement('div');
70 this.waveContainer = document.createElement('div');
71 this.wave.style.backgroundColor = this.color;
72 this.wave.classList.add('wave');
73 this.waveContainer.classList.add('wave-container');
74 Polymer.dom(this.waveContainer).appendChild(this.wave);
75
76 this.resetInteractionState();
77 }
78
79 Ripple.MAX_RADIUS = 300;
80
81 Ripple.prototype = {
82 get recenters() {
83 return this.element.recenters;
84 },
85
86 get center() {
87 return this.element.center;
88 },
89
90 get mouseDownElapsed() {
91 var elapsed;
92
93 if (!this.mouseDownStart) {
94 return 0;
95 }
96
97 elapsed = Utility.now() - this.mouseDownStart;
98
99 if (this.mouseUpStart) {
100 elapsed -= this.mouseUpElapsed;
101 }
102
103 return elapsed;
104 },
105
106 get mouseUpElapsed() {
107 return this.mouseUpStart ?
108 Utility.now () - this.mouseUpStart : 0;
109 },
110
111 get mouseDownElapsedSeconds() {
112 return this.mouseDownElapsed / 1000;
113 },
114
115 get mouseUpElapsedSeconds() {
116 return this.mouseUpElapsed / 1000;
117 },
118
119 get mouseInteractionSeconds() {
120 return this.mouseDownElapsedSeconds + this.mouseUpElapsedSeconds;
121 },
122
123 get initialOpacity() {
124 return this.element.initialOpacity;
125 },
126
127 get opacityDecayVelocity() {
128 return this.element.opacityDecayVelocity;
129 },
130
131 get radius() {
132 var width2 = this.containerMetrics.width * this.containerMetrics.width;
133 var height2 = this.containerMetrics.height * this.containerMetrics.heigh t;
134 var waveRadius = Math.min(
135 Math.sqrt(width2 + height2),
136 Ripple.MAX_RADIUS
137 ) * 1.1 + 5;
138
139 var duration = 1.1 - 0.2 * (waveRadius / Ripple.MAX_RADIUS);
140 var timeNow = this.mouseInteractionSeconds / duration;
141 var size = waveRadius * (1 - Math.pow(80, -timeNow));
142
143 return Math.abs(size);
144 },
145
146 get opacity() {
147 if (!this.mouseUpStart) {
148 return this.initialOpacity;
149 }
150
151 return Math.max(
152 0,
153 this.initialOpacity - this.mouseUpElapsedSeconds * this.opacityDecayVe locity
154 );
155 },
156
157 get outerOpacity() {
158 // Linear increase in background opacity, capped at the opacity
159 // of the wavefront (waveOpacity).
160 var outerOpacity = this.mouseUpElapsedSeconds * 0.3;
161 var waveOpacity = this.opacity;
162
163 return Math.max(
164 0,
165 Math.min(outerOpacity, waveOpacity)
166 );
167 },
168
169 get isOpacityFullyDecayed() {
170 return this.opacity < 0.01 &&
171 this.radius >= Math.min(this.maxRadius, Ripple.MAX_RADIUS);
172 },
173
174 get isRestingAtMaxRadius() {
175 return this.opacity >= this.initialOpacity &&
176 this.radius >= Math.min(this.maxRadius, Ripple.MAX_RADIUS);
177 },
178
179 get isAnimationComplete() {
180 return this.mouseUpStart ?
181 this.isOpacityFullyDecayed : this.isRestingAtMaxRadius;
182 },
183
184 get translationFraction() {
185 return Math.min(
186 1,
187 this.radius / this.containerMetrics.size * 2 / Math.sqrt(2)
188 );
189 },
190
191 get xNow() {
192 if (this.xEnd) {
193 return this.xStart + this.translationFraction * (this.xEnd - this.xSta rt);
194 }
195
196 return this.xStart;
197 },
198
199 get yNow() {
200 if (this.yEnd) {
201 return this.yStart + this.translationFraction * (this.yEnd - this.ySta rt);
202 }
203
204 return this.yStart;
205 },
206
207 get isMouseDown() {
208 return this.mouseDownStart && !this.mouseUpStart;
209 },
210
211 resetInteractionState: function() {
212 this.maxRadius = 0;
213 this.mouseDownStart = 0;
214 this.mouseUpStart = 0;
215
216 this.xStart = 0;
217 this.yStart = 0;
218 this.xEnd = 0;
219 this.yEnd = 0;
220 this.slideDistance = 0;
221
222 this.containerMetrics = new ElementMetrics(this.element);
223 },
224
225 draw: function() {
226 var scale;
227 var translateString;
228 var dx;
229 var dy;
230
231 this.wave.style.opacity = this.opacity;
232
233 scale = this.radius / (this.containerMetrics.size / 2);
234 dx = this.xNow - (this.containerMetrics.width / 2);
235 dy = this.yNow - (this.containerMetrics.height / 2);
236
237
238 // 2d transform for safari because of border-radius and overflow:hidden clipping bug.
239 // https://bugs.webkit.org/show_bug.cgi?id=98538
240 this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy + 'px)';
241 this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + 'px, 0)';
242 this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')';
243 this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)';
244 },
245
246 downAction: function(event) {
247 var xCenter = this.containerMetrics.width / 2;
248 var yCenter = this.containerMetrics.height / 2;
249
250 this.resetInteractionState();
251 this.mouseDownStart = Utility.now();
252
253 if (this.center) {
254 this.xStart = xCenter;
255 this.yStart = yCenter;
256 this.slideDistance = Utility.distance(
257 this.xStart, this.yStart, this.xEnd, this.yEnd
258 );
259 } else {
260 this.xStart = event ?
261 event.detail.x - this.containerMetrics.boundingRect.left :
262 this.containerMetrics.width / 2;
263 this.yStart = event ?
264 event.detail.y - this.containerMetrics.boundingRect.top :
265 this.containerMetrics.height / 2;
266 }
267
268 if (this.recenters) {
269 this.xEnd = xCenter;
270 this.yEnd = yCenter;
271 this.slideDistance = Utility.distance(
272 this.xStart, this.yStart, this.xEnd, this.yEnd
273 );
274 }
275
276 this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom(
277 this.xStart,
278 this.yStart
279 );
280
281 this.waveContainer.style.top =
282 (this.containerMetrics.height - this.containerMetrics.size) / 2 + 'px' ;
283 this.waveContainer.style.left =
284 (this.containerMetrics.width - this.containerMetrics.size) / 2 + 'px';
285
286 this.waveContainer.style.width = this.containerMetrics.size + 'px';
287 this.waveContainer.style.height = this.containerMetrics.size + 'px';
288 },
289
290 upAction: function(event) {
291 if (!this.isMouseDown) {
292 return;
293 }
294
295 this.mouseUpStart = Utility.now();
296 },
297
298 remove: function() {
299 Polymer.dom(this.waveContainer.parentNode).removeChild(
300 this.waveContainer
301 );
302 }
303 };
304
305 Polymer({
306 is: 'paper-ripple',
307
308 behaviors: [
309 Polymer.IronA11yKeysBehavior
310 ],
311
312 properties: {
313 /**
314 * The initial opacity set on the wave.
315 *
316 * @attribute initialOpacity
317 * @type number
318 * @default 0.25
319 */
320 initialOpacity: {
321 type: Number,
322 value: 0.25
323 },
324
325 /**
326 * How fast (opacity per second) the wave fades out.
327 *
328 * @attribute opacityDecayVelocity
329 * @type number
330 * @default 0.8
331 */
332 opacityDecayVelocity: {
333 type: Number,
334 value: 0.8
335 },
336
337 /**
338 * If true, ripples will exhibit a gravitational pull towards
339 * the center of their container as they fade away.
340 *
341 * @attribute recenters
342 * @type boolean
343 * @default false
344 */
345 recenters: {
346 type: Boolean,
347 value: false
348 },
349
350 /**
351 * If true, ripples will center inside its container
352 *
353 * @attribute recenters
354 * @type boolean
355 * @default false
356 */
357 center: {
358 type: Boolean,
359 value: false
360 },
361
362 /**
363 * A list of the visual ripples.
364 *
365 * @attribute ripples
366 * @type Array
367 * @default []
368 */
369 ripples: {
370 type: Array,
371 value: function() {
372 return [];
373 }
374 },
375
376 /**
377 * True when there are visible ripples animating within the
378 * element.
379 */
380 animating: {
381 type: Boolean,
382 readOnly: true,
383 reflectToAttribute: true,
384 value: false
385 },
386
387 /**
388 * If true, the ripple will remain in the "down" state until `holdDown`
389 * is set to false again.
390 */
391 holdDown: {
392 type: Boolean,
393 value: false,
394 observer: '_holdDownChanged'
395 },
396
397 _animating: {
398 type: Boolean
399 },
400
401 _boundAnimate: {
402 type: Function,
403 value: function() {
404 return this.animate.bind(this);
405 }
406 }
407 },
408
409 get target () {
410 var ownerRoot = Polymer.dom(this).getOwnerRoot();
411 var target;
412
413 if (ownerRoot) {
414 target = ownerRoot.host;
415 }
416
417 if (!target) {
418 target = this.parentNode;
419 }
420
421 return target;
422 },
423
424 keyBindings: {
425 'enter:keydown': '_onEnterKeydown',
426 'space:keydown': '_onSpaceKeydown',
427 'space:keyup': '_onSpaceKeyup'
428 },
429
430 attached: function() {
431 this._listen(this.target, 'up', this.upAction.bind(this));
432 this._listen(this.target, 'down', this.downAction.bind(this));
433
434 if (!this.target.hasAttribute('noink')) {
435 this.keyEventTarget = this.target;
436 }
437 },
438
439 get shouldKeepAnimating () {
440 for (var index = 0; index < this.ripples.length; ++index) {
441 if (!this.ripples[index].isAnimationComplete) {
442 return true;
443 }
444 }
445
446 return false;
447 },
448
449 simulatedRipple: function() {
450 this.downAction(null);
451
452 // Please see polymer/polymer#1305
453 this.async(function() {
454 this.upAction();
455 }, 1);
456 },
457
458 downAction: function(event) {
459 if (this.holdDown && this.ripples.length > 0) {
460 return;
461 }
462
463 var ripple = this.addRipple();
464
465 ripple.downAction(event);
466
467 if (!this._animating) {
468 this.animate();
469 }
470 },
471
472 upAction: function(event) {
473 if (this.holdDown) {
474 return;
475 }
476
477 this.ripples.forEach(function(ripple) {
478 ripple.upAction(event);
479 });
480
481 this.animate();
482 },
483
484 onAnimationComplete: function() {
485 this._animating = false;
486 this.$.background.style.backgroundColor = null;
487 this.fire('transitionend');
488 },
489
490 addRipple: function() {
491 var ripple = new Ripple(this);
492
493 Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);
494 this.$.background.style.backgroundColor = ripple.color;
495 this.ripples.push(ripple);
496
497 this._setAnimating(true);
498
499 return ripple;
500 },
501
502 removeRipple: function(ripple) {
503 var rippleIndex = this.ripples.indexOf(ripple);
504
505 if (rippleIndex < 0) {
506 return;
507 }
508
509 this.ripples.splice(rippleIndex, 1);
510
511 ripple.remove();
512
513 if (!this.ripples.length) {
514 this._setAnimating(false);
515 }
516 },
517
518 animate: function() {
519 var index;
520 var ripple;
521
522 this._animating = true;
523
524 for (index = 0; index < this.ripples.length; ++index) {
525 ripple = this.ripples[index];
526
527 ripple.draw();
528
529 this.$.background.style.opacity = ripple.outerOpacity;
530
531 if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) {
532 this.removeRipple(ripple);
533 }
534 }
535
536 if (!this.shouldKeepAnimating && this.ripples.length === 0) {
537 this.onAnimationComplete();
538 } else {
539 window.requestAnimationFrame(this._boundAnimate);
540 }
541 },
542
543 _onEnterKeydown: function() {
544 this.downAction();
545 this.async(this.upAction, 1);
546 },
547
548 _onSpaceKeydown: function() {
549 this.downAction();
550 },
551
552 _onSpaceKeyup: function() {
553 this.upAction();
554 },
555
556 _holdDownChanged: function(holdDown) {
557 if (holdDown) {
558 this.downAction();
559 } else {
560 this.upAction();
561 }
562 }
563 });
564 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698