ripple.js 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { isActivatedDisabled } from './activator-base';
  2. import { Activator } from './activator';
  3. import { hasPointerMoved, pointerCoord } from '../util/dom';
  4. /**
  5. * @hidden
  6. */
  7. export class RippleActivator {
  8. constructor(app, config, dom) {
  9. this.dom = dom;
  10. this.highlight = new Activator(app, config, dom);
  11. }
  12. clickAction(ev, activatableEle, startCoord) {
  13. // Highlight
  14. this.highlight && this.highlight.clickAction(ev, activatableEle, startCoord);
  15. // Ripple
  16. this._clickAction(ev, activatableEle, startCoord);
  17. }
  18. downAction(ev, activatableEle, startCoord) {
  19. // Highlight
  20. this.highlight && this.highlight.downAction(ev, activatableEle, startCoord);
  21. // Ripple
  22. this._downAction(ev, activatableEle, startCoord);
  23. }
  24. upAction(ev, activatableEle, startCoord) {
  25. // Highlight
  26. this.highlight && this.highlight.upAction(ev, activatableEle, startCoord);
  27. // Ripple
  28. this._upAction(ev, activatableEle, startCoord);
  29. }
  30. clearState(animated) {
  31. // Highlight
  32. this.highlight && this.highlight.clearState(animated);
  33. }
  34. _downAction(ev, activatableEle, _startCoord) {
  35. if (isActivatedDisabled(ev, activatableEle)) {
  36. return;
  37. }
  38. var j = activatableEle.childElementCount;
  39. while (j--) {
  40. var rippleEle = activatableEle.children[j];
  41. if (rippleEle.classList.contains('button-effect')) {
  42. // DOM READ
  43. var clientRect = activatableEle.getBoundingClientRect();
  44. rippleEle.$top = clientRect.top;
  45. rippleEle.$left = clientRect.left;
  46. rippleEle.$width = clientRect.width;
  47. rippleEle.$height = clientRect.height;
  48. break;
  49. }
  50. }
  51. }
  52. _upAction(ev, activatableEle, startCoord) {
  53. if (!hasPointerMoved(6, startCoord, pointerCoord(ev))) {
  54. let i = activatableEle.childElementCount;
  55. while (i--) {
  56. var rippleEle = activatableEle.children[i];
  57. if (rippleEle.classList.contains('button-effect')) {
  58. // DOM WRITE
  59. this.startRippleEffect(rippleEle, activatableEle, startCoord);
  60. break;
  61. }
  62. }
  63. }
  64. }
  65. _clickAction(_ev, _activatableEle, _startCoord) {
  66. // NOTHING
  67. }
  68. startRippleEffect(rippleEle, activatableEle, startCoord) {
  69. if (!startCoord) {
  70. return;
  71. }
  72. let clientPointerX = (startCoord.x - rippleEle.$left);
  73. let clientPointerY = (startCoord.y - rippleEle.$top);
  74. let x = Math.max(Math.abs(rippleEle.$width - clientPointerX), clientPointerX) * 2;
  75. let y = Math.max(Math.abs(rippleEle.$height - clientPointerY), clientPointerY) * 2;
  76. let diameter = Math.min(Math.max(Math.hypot(x, y), 64), 240);
  77. if (activatableEle.hasAttribute('ion-item')) {
  78. diameter = Math.min(diameter, 140);
  79. }
  80. clientPointerX -= diameter / 2;
  81. clientPointerY -= diameter / 2;
  82. clientPointerX = Math.round(clientPointerX);
  83. clientPointerY = Math.round(clientPointerY);
  84. diameter = Math.round(diameter);
  85. // Reset ripple
  86. // DOM WRITE
  87. const Css = this.dom.plt.Css;
  88. rippleEle.style.opacity = '';
  89. rippleEle.style[Css.transform] = `translate3d(${clientPointerX}px, ${clientPointerY}px, 0px) scale(0.001)`;
  90. rippleEle.style[Css.transition] = '';
  91. // Start ripple animation
  92. let radius = Math.sqrt(rippleEle.$width + rippleEle.$height);
  93. let scaleTransitionDuration = Math.max(1600 * Math.sqrt(radius / TOUCH_DOWN_ACCEL) + 0.5, 260);
  94. let opacityTransitionDuration = Math.round(scaleTransitionDuration * 0.7);
  95. let opacityTransitionDelay = Math.round(scaleTransitionDuration - opacityTransitionDuration);
  96. scaleTransitionDuration = Math.round(scaleTransitionDuration);
  97. let transform = `translate3d(${clientPointerX}px, ${clientPointerY}px, 0px) scale(1)`;
  98. let transition = `transform ${scaleTransitionDuration}ms,opacity ${opacityTransitionDuration}ms ${opacityTransitionDelay}ms`;
  99. this.dom.write(() => {
  100. // DOM WRITE
  101. rippleEle.style.width = rippleEle.style.height = diameter + 'px';
  102. rippleEle.style.opacity = '0';
  103. rippleEle.style[Css.transform] = transform;
  104. rippleEle.style[Css.transition] = transition;
  105. }, 16);
  106. }
  107. }
  108. const TOUCH_DOWN_ACCEL = 300;
  109. //# sourceMappingURL=ripple.js.map