UNPKG

7.3 kBJavaScriptView Raw
1/** TODO: internal */
2export var ForegroundRippleState;
3(function (ForegroundRippleState) {
4 ForegroundRippleState[ForegroundRippleState["NEW"] = 0] = "NEW";
5 ForegroundRippleState[ForegroundRippleState["EXPANDING"] = 1] = "EXPANDING";
6 ForegroundRippleState[ForegroundRippleState["FADING_OUT"] = 2] = "FADING_OUT";
7})(ForegroundRippleState || (ForegroundRippleState = {}));
8/**
9 * Wrapper for a foreground ripple DOM element and its animation state.
10 * TODO: internal
11 */
12export var ForegroundRipple = (function () {
13 function ForegroundRipple(rippleElement) {
14 this.rippleElement = rippleElement;
15 this.state = ForegroundRippleState.NEW;
16 }
17 return ForegroundRipple;
18}());
19var RIPPLE_SPEED_PX_PER_SECOND = 1000;
20var MIN_RIPPLE_FILL_TIME_SECONDS = 0.1;
21var MAX_RIPPLE_FILL_TIME_SECONDS = 0.3;
22/**
23 * Returns the distance from the point (x, y) to the furthest corner of a rectangle.
24 */
25var distanceToFurthestCorner = function (x, y, rect) {
26 var distX = Math.max(Math.abs(x - rect.left), Math.abs(x - rect.right));
27 var distY = Math.max(Math.abs(y - rect.top), Math.abs(y - rect.bottom));
28 return Math.sqrt(distX * distX + distY * distY);
29};
30/**
31 * Helper service that performs DOM manipulations. Not intended to be used outside this module.
32 * The constructor takes a reference to the ripple directive's host element and a map of DOM
33 * event handlers to be installed on the element that triggers ripple animations.
34 * This will eventually become a custom renderer once Angular support exists.
35 * TODO: internal
36 */
37export var RippleRenderer = (function () {
38 function RippleRenderer(_elementRef, _eventHandlers) {
39 this._eventHandlers = _eventHandlers;
40 this._rippleElement = _elementRef.nativeElement;
41 // It might be nice to delay creating the background until it's needed, but doing this in
42 // fadeInRippleBackground causes the first click event to not be handled reliably.
43 this._backgroundDiv = document.createElement('div');
44 this._backgroundDiv.classList.add('md-ripple-background');
45 this._rippleElement.appendChild(this._backgroundDiv);
46 }
47 /**
48 * Installs event handlers on the given trigger element, and removes event handlers from the
49 * previous trigger if needed.
50 */
51 RippleRenderer.prototype.setTriggerElement = function (newTrigger) {
52 var _this = this;
53 if (this._triggerElement !== newTrigger) {
54 if (this._triggerElement) {
55 this._eventHandlers.forEach(function (eventHandler, eventName) {
56 _this._triggerElement.removeEventListener(eventName, eventHandler);
57 });
58 }
59 this._triggerElement = newTrigger;
60 if (this._triggerElement) {
61 this._eventHandlers.forEach(function (eventHandler, eventName) {
62 _this._triggerElement.addEventListener(eventName, eventHandler);
63 });
64 }
65 }
66 };
67 /**
68 * Installs event handlers on the host element of the md-ripple directive.
69 */
70 RippleRenderer.prototype.setTriggerElementToHost = function () {
71 this.setTriggerElement(this._rippleElement);
72 };
73 /**
74 * Removes event handlers from the current trigger element if needed.
75 */
76 RippleRenderer.prototype.clearTriggerElement = function () {
77 this.setTriggerElement(null);
78 };
79 /**
80 * Creates a foreground ripple and sets its animation to expand and fade in from the position
81 * given by rippleOriginLeft and rippleOriginTop (or from the center of the <md-ripple>
82 * bounding rect if centered is true).
83 */
84 RippleRenderer.prototype.createForegroundRipple = function (rippleOriginLeft, rippleOriginTop, color, centered, radius, speedFactor, transitionEndCallback) {
85 var parentRect = this._rippleElement.getBoundingClientRect();
86 // Create a foreground ripple div with the size and position of the fully expanded ripple.
87 // When the div is created, it's given a transform style that causes the ripple to be displayed
88 // small and centered on the event location (or the center of the bounding rect if the centered
89 // argument is true). Removing that transform causes the ripple to animate to its natural size.
90 var startX = centered ? (parentRect.left + parentRect.width / 2) : rippleOriginLeft;
91 var startY = centered ? (parentRect.top + parentRect.height / 2) : rippleOriginTop;
92 var offsetX = startX - parentRect.left;
93 var offsetY = startY - parentRect.top;
94 var maxRadius = radius > 0 ? radius : distanceToFurthestCorner(startX, startY, parentRect);
95 var rippleDiv = document.createElement('div');
96 this._rippleElement.appendChild(rippleDiv);
97 rippleDiv.classList.add('md-ripple-foreground');
98 rippleDiv.style.left = (offsetX - maxRadius) + "px";
99 rippleDiv.style.top = (offsetY - maxRadius) + "px";
100 rippleDiv.style.width = 2 * maxRadius + "px";
101 rippleDiv.style.height = rippleDiv.style.width;
102 // If color input is not set, this will default to the background color defined in CSS.
103 rippleDiv.style.backgroundColor = color;
104 // Start the ripple tiny.
105 rippleDiv.style.transform = "scale(0.001)";
106 var fadeInSeconds = (1 / (speedFactor || 1)) * Math.max(MIN_RIPPLE_FILL_TIME_SECONDS, Math.min(MAX_RIPPLE_FILL_TIME_SECONDS, maxRadius / RIPPLE_SPEED_PX_PER_SECOND));
107 rippleDiv.style.transitionDuration = fadeInSeconds + "s";
108 // https://timtaubert.de/blog/2012/09/css-transitions-for-dynamically-created-dom-elements/
109 window.getComputedStyle(rippleDiv).opacity;
110 rippleDiv.classList.add('md-ripple-fade-in');
111 // Clearing the transform property causes the ripple to animate to its full size.
112 rippleDiv.style.transform = '';
113 var ripple = new ForegroundRipple(rippleDiv);
114 ripple.state = ForegroundRippleState.EXPANDING;
115 rippleDiv.addEventListener('transitionend', function (event) { return transitionEndCallback(ripple, event); });
116 };
117 /**
118 * Fades out a foreground ripple after it has fully expanded and faded in.
119 */
120 RippleRenderer.prototype.fadeOutForegroundRipple = function (ripple) {
121 ripple.classList.remove('md-ripple-fade-in');
122 ripple.classList.add('md-ripple-fade-out');
123 };
124 /**
125 * Removes a foreground ripple from the DOM after it has faded out.
126 */
127 RippleRenderer.prototype.removeRippleFromDom = function (ripple) {
128 ripple.parentElement.removeChild(ripple);
129 };
130 /**
131 * Fades in the ripple background.
132 */
133 RippleRenderer.prototype.fadeInRippleBackground = function (color) {
134 this._backgroundDiv.classList.add('md-ripple-active');
135 // If color is not set, this will default to the background color defined in CSS.
136 this._backgroundDiv.style.backgroundColor = color;
137 };
138 /**
139 * Fades out the ripple background.
140 */
141 RippleRenderer.prototype.fadeOutRippleBackground = function () {
142 if (this._backgroundDiv) {
143 this._backgroundDiv.classList.remove('md-ripple-active');
144 }
145 };
146 return RippleRenderer;
147}());
148
149//# sourceMappingURL=ripple-renderer.js.map