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

Side by Side Diff: third_party/polymer/v0_8/components/paper-ripple/paper-ripple.html

Issue 1162563004: Upgrade to 1.0 and switch clients to dom-repeat where needed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix a layout import and remove the gzipped webanimation in reproduce.sh 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
1 <!-- 1 <!--
2 Copyright (c) 2014 The Polymer Project Authors. All rights reserved. 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 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 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 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 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 7 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS.txt
8 --> 8 -->
9 9
10 <link rel="import" href="../polymer/polymer.html">
11 <link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html ">
12
10 <!-- 13 <!--
11 `paper-ripple` provides a visual effect that other paper elements can 14 `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 15 use to simulate a rippling effect emanating from the point of contact. The
13 effect can be visualized as a concentric circle with motion. 16 effect can be visualized as a concentric circle with motion.
14 17
15 Example: 18 Example:
16 19
17 <paper-ripple></paper-ripple> 20 <paper-ripple></paper-ripple>
18 21
19 `paper-ripple` listens to "mousedown" and "mouseup" events so it would display r ipple 22 `paper-ripple` listens to "mousedown" and "mouseup" events so it would display r ipple
20 effect when touches on it. You can also defeat the default behavior and 23 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 24 manually route the down and up actions to the ripple element. Note that it is
22 important if you call mousedownAction() you will have to make sure to call 25 important if you call downAction() you will have to make sure to call
23 mouseupAction() so that `paper-ripple` would end the animation loop. 26 upAction() so that `paper-ripple` would end the animation loop.
24 27
25 Example: 28 Example:
26 29
27 <paper-ripple id="ripple" style="pointer-events: none;"></paper-ripple> 30 <paper-ripple id="ripple" style="pointer-events: none;"></paper-ripple>
28 ... 31 ...
29 downAction: function(e) { 32 downAction: function(e) {
30 this.$.ripple.mousedownAction({x: e.x, y: e.y}); 33 this.$.ripple.downAction({x: e.x, y: e.y});
31 }, 34 },
32 upAction: function(e) { 35 upAction: function(e) {
33 this.$.ripple.mouseupAction(); 36 this.$.ripple.upAction();
34 } 37 }
35 38
36 Styling ripple effect: 39 Styling ripple effect:
37 40
38 Use CSS color property to style the ripple: 41 Use CSS color property to style the ripple:
39 42
40 paper-ripple { 43 paper-ripple {
41 color: #4285f4; 44 color: #4285f4;
42 } 45 }
43 46
44 Note that CSS color property is inherited so it is not required to set it on 47 Note that CSS color property is inherited so it is not required to set it on
45 the `paper-ripple` element directly. 48 the `paper-ripple` element directly.
46 49
47 By default, the ripple is centered on the point of contact. Apply the `recenter s` 50 By default, the ripple is centered on the point of contact. Apply the `recenter s`
48 attribute to have the ripple grow toward the center of its container. 51 attribute to have the ripple grow toward the center of its container.
49 52
50 <paper-ripple recenters></paper-ripple> 53 <paper-ripple recenters></paper-ripple>
51 54
55 You can also center the ripple inside its container from the start.
56
57 <paper-ripple center></paper-ripple>
58
52 Apply `circle` class to make the rippling effect within a circle. 59 Apply `circle` class to make the rippling effect within a circle.
53 60
54 <paper-ripple class="circle"></paper-ripple> 61 <paper-ripple class="circle"></paper-ripple>
55 62
56 @group Paper Elements 63 @group Paper Elements
57 @element paper-ripple 64 @element paper-ripple
58 @homepage github.io 65 @hero hero.svg
66 @demo demo/index.html
59 --> 67 -->
60 68
61 <!-- 69 <dom-module id="paper-ripple">
62 Fired when the animation finishes. This is useful if you want to wait until the ripple
63 animation finishes to perform some action.
64 70
65 @event transitionend 71 <!--
66 @param {Object} detail 72 Fired when the animation finishes. This is useful if you want to wait until th e ripple
67 @param {Object} detail.node The animated node 73 animation finishes to perform some action.
68 -->
69 74
70 <link rel="import" href="../polymer/polymer.html"> 75 @event transitionend
76 @param {Object} detail
77 @param {Object} detail.node The animated node
78 -->
71 79
72 <dom-module id="paper-ripple">
73 <style> 80 <style>
74 :host { 81 :host {
75 display: block; 82 display: block;
76 position: absolute; 83 position: absolute;
77 border-radius: inherit; 84 border-radius: inherit;
78 overflow: hidden; 85 overflow: hidden;
79 top: 0; 86 top: 0;
80 left: 0; 87 left: 0;
81 right: 0; 88 right: 0;
82 bottom: 0; 89 bottom: 0;
90 }
83 91
84 /* This resolves a rendering issue in Chrome 40 where the 92 :host([animating]) {
93 /* This resolves a rendering issue in Chrome (as of 40) where the
85 ripple is not properly clipped by its parent (which may have 94 ripple is not properly clipped by its parent (which may have
86 rounded corners. See: http://jsbin.com/temexa/4 */ 95 rounded corners). See: http://jsbin.com/temexa/4
96
97 Note: We only apply this style conditionally. Otherwise, the browser
98 will create a new compositing layer for every ripple element on the
99 page, and that would be bad. */
87 -webkit-transform: translate(0, 0); 100 -webkit-transform: translate(0, 0);
88 transform: translate3d(0, 0, 0); 101 transform: translate3d(0, 0, 0);
89 } 102 }
90 103
91 :host([noink]) { 104 :host([noink]) {
92 pointer-events: none; 105 pointer-events: none;
93 } 106 }
94 107
95 #background, 108 #background,
96 #waves, 109 #waves,
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 this.resetInteractionState(); 225 this.resetInteractionState();
213 } 226 }
214 227
215 Ripple.MAX_RADIUS = 300; 228 Ripple.MAX_RADIUS = 300;
216 229
217 Ripple.prototype = { 230 Ripple.prototype = {
218 get recenters() { 231 get recenters() {
219 return this.element.recenters; 232 return this.element.recenters;
220 }, 233 },
221 234
235 get center() {
236 return this.element.center;
237 },
238
222 get mouseDownElapsed() { 239 get mouseDownElapsed() {
223 var elapsed; 240 var elapsed;
224 241
225 if (!this.mouseDownStart) { 242 if (!this.mouseDownStart) {
226 return 0; 243 return 0;
227 } 244 }
228 245
229 elapsed = Utility.now() - this.mouseDownStart; 246 elapsed = Utility.now() - this.mouseDownStart;
230 247
231 if (this.mouseUpStart) { 248 if (this.mouseUpStart) {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 385
369 386
370 // 2d transform for safari because of border-radius and overflow:hidden clipping bug. 387 // 2d transform for safari because of border-radius and overflow:hidden clipping bug.
371 // https://bugs.webkit.org/show_bug.cgi?id=98538 388 // https://bugs.webkit.org/show_bug.cgi?id=98538
372 this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy + 'px)'; 389 this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy + 'px)';
373 this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + 'px, 0)'; 390 this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + 'px, 0)';
374 this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')'; 391 this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')';
375 this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)'; 392 this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)';
376 }, 393 },
377 394
378 mousedownAction: function(event) { 395 downAction: function(event) {
396 var xCenter = this.containerMetrics.width / 2;
397 var yCenter = this.containerMetrics.height / 2;
398
379 this.resetInteractionState(); 399 this.resetInteractionState();
380 this.mouseDownStart = Utility.now(); 400 this.mouseDownStart = Utility.now();
381 401
382 this.xStart = event ? 402 if (this.center) {
383 event.x - this.containerMetrics.boundingRect.left : 403 this.xStart = xCenter;
384 this.containerMetrics.width / 2; 404 this.yStart = yCenter;
385 this.yStart = event ?
386 event.y - this.containerMetrics.boundingRect.top :
387 this.containerMetrics.height / 2;
388
389 if (this.recenters) {
390 this.xEnd = this.containerMetrics.width / 2;
391 this.yEnd = this.containerMetrics.height / 2;
392 this.slideDistance = Utility.distance( 405 this.slideDistance = Utility.distance(
393 this.xStart, this.yStart, this.xEnd, this.yEnd 406 this.xStart, this.yStart, this.xEnd, this.yEnd
394 ); 407 );
408 } else {
409 this.xStart = event ?
410 event.detail.x - this.containerMetrics.boundingRect.left :
411 this.containerMetrics.width / 2;
412 this.yStart = event ?
413 event.detail.y - this.containerMetrics.boundingRect.top :
414 this.containerMetrics.height / 2;
415 }
416
417 if (this.recenters) {
418 this.xEnd = xCenter;
419 this.yEnd = yCenter;
420 this.slideDistance = Utility.distance(
421 this.xStart, this.yStart, this.xEnd, this.yEnd
422 );
395 } 423 }
396 424
397 this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom( 425 this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom(
398 this.xStart, 426 this.xStart,
399 this.yStart 427 this.yStart
400 ); 428 );
401 429
402 this.waveContainer.style.top = 430 this.waveContainer.style.top =
403 (this.containerMetrics.height - this.containerMetrics.size) / 2 + 'px' ; 431 (this.containerMetrics.height - this.containerMetrics.size) / 2 + 'px' ;
404 this.waveContainer.style.left = 432 this.waveContainer.style.left =
405 (this.containerMetrics.width - this.containerMetrics.size) / 2 + 'px'; 433 (this.containerMetrics.width - this.containerMetrics.size) / 2 + 'px';
406 434
407 this.waveContainer.style.width = this.containerMetrics.size + 'px'; 435 this.waveContainer.style.width = this.containerMetrics.size + 'px';
408 this.waveContainer.style.height = this.containerMetrics.size + 'px'; 436 this.waveContainer.style.height = this.containerMetrics.size + 'px';
409 }, 437 },
410 438
411 mouseupAction: function(event) { 439 upAction: function(event) {
412 if (!this.isMouseDown) { 440 if (!this.isMouseDown) {
413 return; 441 return;
414 } 442 }
415 443
416 this.mouseUpStart = Utility.now(); 444 this.mouseUpStart = Utility.now();
417 }, 445 },
418 446
419 remove: function() { 447 remove: function() {
420 Polymer.dom(this.waveContainer.parentNode).removeChild( 448 Polymer.dom(this.waveContainer.parentNode).removeChild(
421 this.waveContainer 449 this.waveContainer
422 ); 450 );
423 } 451 }
424 }; 452 };
425 453
426 Polymer({ 454 Polymer({
427 is: 'paper-ripple', 455 is: 'paper-ripple',
428 456
457 behaviors: [
458 Polymer.IronA11yKeysBehavior
459 ],
460
429 properties: { 461 properties: {
430 /** 462 /**
431 * The initial opacity set on the wave. 463 * The initial opacity set on the wave.
432 * 464 *
433 * @attribute initialOpacity 465 * @attribute initialOpacity
434 * @type number 466 * @type number
435 * @default 0.25 467 * @default 0.25
436 */ 468 */
437 initialOpacity: { 469 initialOpacity: {
438 type: Number, 470 type: Number,
(...skipping 19 matching lines...) Expand all
458 * @attribute recenters 490 * @attribute recenters
459 * @type boolean 491 * @type boolean
460 * @default false 492 * @default false
461 */ 493 */
462 recenters: { 494 recenters: {
463 type: Boolean, 495 type: Boolean,
464 value: false 496 value: false
465 }, 497 },
466 498
467 /** 499 /**
500 * If true, ripples will center inside its container
501 *
502 * @attribute recenters
503 * @type boolean
504 * @default false
505 */
506 center: {
507 type: Boolean,
508 value: false
509 },
510
511 /**
468 * A list of the visual ripples. 512 * A list of the visual ripples.
469 * 513 *
470 * @attribute ripples 514 * @attribute ripples
471 * @type Array 515 * @type Array
472 * @default [] 516 * @default []
473 */ 517 */
474 ripples: { 518 ripples: {
475 type: Array, 519 type: Array,
476 value: function() { 520 value: function() {
477 return []; 521 return [];
478 } 522 }
479 }, 523 },
480 524
525 /**
526 * True when there are visible ripples animating within the
527 * element.
528 */
529 animating: {
530 type: Boolean,
531 readOnly: true,
532 reflectToAttribute: true,
533 value: false
534 },
535
536 /**
537 * If true, the ripple will remain in the "down" state until `holdDown`
538 * is set to false again.
539 */
540 holdDown: {
541 type: Boolean,
542 value: false,
543 observer: '_holdDownChanged'
544 },
545
481 _animating: { 546 _animating: {
482 type: Boolean 547 type: Boolean
483 }, 548 },
484 549
485 _boundAnimate: { 550 _boundAnimate: {
486 type: Function, 551 type: Function,
487 value: function() { 552 value: function() {
488 return this.animate.bind(this); 553 return this.animate.bind(this);
489 } 554 }
490 },
491
492 _boundMousedownAction: {
493 type: Function,
494 value: function() {
495 return this.mousedownAction.bind(this);
496 }
497 },
498
499 _boundMouseupAction: {
500 type: Function,
501 value: function() {
502 return this.mouseupAction.bind(this);
503 }
504 } 555 }
505 }, 556 },
506 557
507 get target () { 558 get target () {
508 return this.host || this.parentNode; 559 var ownerRoot = Polymer.dom(this).getOwnerRoot();
560 var target;
561
562 if (ownerRoot) {
563 target = ownerRoot.host;
564 }
565
566 if (!target) {
567 target = this.parentNode;
568 }
569
570 return target;
571 },
572
573 keyBindings: {
574 'enter:keydown': '_onEnterKeydown',
575 'space:keydown': '_onSpaceKeydown',
576 'space:keyup': '_onSpaceKeyup'
509 }, 577 },
510 578
511 attached: function() { 579 attached: function() {
512 this.target.addEventListener('mousedown', this._boundMousedownAction); 580 this._listen(this.target, 'up', this.upAction.bind(this));
513 this.target.addEventListener('mouseup', this._boundMouseupAction); 581 this._listen(this.target, 'down', this.downAction.bind(this));
582
583 if (!this.target.hasAttribute('noink')) {
584 this.keyEventTarget = this.target;
585 }
514 }, 586 },
515 587
516 detached: function() {
517 this.target.removeEventListener('mousedown', this._boundMousedownAction) ;
518 this.target.removeEventListener('mouseup', this._boundMouseupAction);
519 },
520
521 /* TODO(cdata): Replace the above attached / detached listeners when
522 PolymerGestures equivalent lands in 0.8.
523 listeners: {
524 mousedown: 'mousedownAction',
525 mouseup: 'mouseupAction'
526 },
527 */
528
529 get shouldKeepAnimating () { 588 get shouldKeepAnimating () {
530 for (var index = 0; index < this.ripples.length; ++index) { 589 for (var index = 0; index < this.ripples.length; ++index) {
531 if (!this.ripples[index].isAnimationComplete) { 590 if (!this.ripples[index].isAnimationComplete) {
532 return true; 591 return true;
533 } 592 }
534 } 593 }
535 594
536 return false; 595 return false;
537 }, 596 },
538 597
539 simulatedRipple: function() { 598 simulatedRipple: function() {
540 this.mousedownAction(null); 599 this.downAction(null);
541 600
542 // Please see polymer/polymer#1305 601 // Please see polymer/polymer#1305
543 this.async(function() { 602 this.async(function() {
544 this.mouseupAction(); 603 this.upAction();
545 }, 1); 604 }, 1);
546 }, 605 },
547 606
548 mousedownAction: function(event) { 607 downAction: function(event) {
608 if (this.holdDown && this.ripples.length > 0) {
609 return;
610 }
611
549 var ripple = this.addRipple(); 612 var ripple = this.addRipple();
550 613
551 ripple.mousedownAction(event); 614 ripple.downAction(event);
552 615
553 if (!this._animating) { 616 if (!this._animating) {
554 this.animate(); 617 this.animate();
555 } 618 }
556 }, 619 },
557 620
558 mouseupAction: function(event) { 621 upAction: function(event) {
622 if (this.holdDown) {
623 return;
624 }
625
559 this.ripples.forEach(function(ripple) { 626 this.ripples.forEach(function(ripple) {
560 ripple.mouseupAction(event); 627 ripple.upAction(event);
561 }); 628 });
562 629
563 this.animate(); 630 this.animate();
564 }, 631 },
565 632
566 onAnimationComplete: function() { 633 onAnimationComplete: function() {
567 this._animating = false; 634 this._animating = false;
568 this.$.background.style.backgroundColor = null; 635 this.$.background.style.backgroundColor = null;
569 this.fire('transitionend'); 636 this.fire('transitionend');
570 }, 637 },
571 638
572 addRipple: function() { 639 addRipple: function() {
573 var ripple = new Ripple(this); 640 var ripple = new Ripple(this);
574 641
575 Polymer.dom(this.$.waves).appendChild(ripple.waveContainer); 642 Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);
576 this.$.background.style.backgroundColor = ripple.color; 643 this.$.background.style.backgroundColor = ripple.color;
577 this.ripples.push(ripple); 644 this.ripples.push(ripple);
578 645
646 this._setAnimating(true);
647
579 return ripple; 648 return ripple;
580 }, 649 },
581 650
582 removeRipple: function(ripple) { 651 removeRipple: function(ripple) {
583 var rippleIndex = this.ripples.indexOf(ripple); 652 var rippleIndex = this.ripples.indexOf(ripple);
584 653
585 if (rippleIndex < 0) { 654 if (rippleIndex < 0) {
586 return; 655 return;
587 } 656 }
588 657
589 this.ripples.splice(rippleIndex, 1); 658 this.ripples.splice(rippleIndex, 1);
590 659
591 ripple.remove(); 660 ripple.remove();
661
662 if (!this.ripples.length) {
663 this._setAnimating(false);
664 }
592 }, 665 },
593 666
594 animate: function() { 667 animate: function() {
595 var index; 668 var index;
596 var ripple; 669 var ripple;
597 670
598 this._animating = true; 671 this._animating = true;
599 672
600 for (index = 0; index < this.ripples.length; ++index) { 673 for (index = 0; index < this.ripples.length; ++index) {
601 ripple = this.ripples[index]; 674 ripple = this.ripples[index];
602 675
603 ripple.draw(); 676 ripple.draw();
604 677
605 this.$.background.style.opacity = ripple.outerOpacity; 678 this.$.background.style.opacity = ripple.outerOpacity;
606 679
607 if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) { 680 if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) {
608 this.removeRipple(ripple); 681 this.removeRipple(ripple);
609 } 682 }
610 } 683 }
611 684
612 if (this.shouldKeepAnimating) { 685 if (!this.shouldKeepAnimating && this.ripples.length === 0) {
686 this.onAnimationComplete();
687 } else {
613 window.requestAnimationFrame(this._boundAnimate); 688 window.requestAnimationFrame(this._boundAnimate);
614 } else if (this.ripples.length === 0) { 689 }
615 this.onAnimationComplete(); 690 },
691
692 _onEnterKeydown: function() {
693 this.downAction();
694 this.async(this.upAction, 1);
695 },
696
697 _onSpaceKeydown: function() {
698 this.downAction();
699 },
700
701 _onSpaceKeyup: function() {
702 this.upAction();
703 },
704
705 _holdDownChanged: function(holdDown) {
706 if (holdDown) {
707 this.downAction();
708 } else {
709 this.upAction();
616 } 710 }
617 } 711 }
618 }); 712 });
619 })(); 713 })();
620 </script> 714 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698