UNPKG

iuap-design

Version:
199 lines (173 loc) 6.32 kB
var URipple = function URipple(element) { if (u.isIE8) return; this._element = element; // Initialize instance. this.init(); }; //window['URipple'] = URipple; URipple.prototype._down = function(event) { if (u.isIE8) return; if (!this._rippleElement.style.width && !this._rippleElement.style.height) { var rect = this._element.getBoundingClientRect(); this.rippleSize_ = Math.sqrt(rect.width * rect.width + rect.height * rect.height) * 2 + 2; this._rippleElement.style.width = this.rippleSize_ + 'px'; this._rippleElement.style.height = this.rippleSize_ + 'px'; } u.addClass(this._rippleElement, 'is-visible'); if (event.type === 'mousedown' && this._ignoringMouseDown) { this._ignoringMouseDown = false; } else { if (event.type === 'touchstart') { this._ignoringMouseDown = true; } var frameCount = this.getFrameCount(); if (frameCount > 0) { return; } this.setFrameCount(1); var t = event.currentTarget || event.target || event.srcElement; var bound = t.getBoundingClientRect(); var x; var y; // Check if we are handling a keyboard click. if (event.clientX === 0 && event.clientY === 0) { x = Math.round(bound.width / 2); y = Math.round(bound.height / 2); } else { var clientX = event.clientX ? event.clientX : event.touches[0].clientX; var clientY = event.clientY ? event.clientY : event.touches[0].clientY; x = Math.round(clientX - bound.left); y = Math.round(clientY - bound.top); } this.setRippleXY(x, y); this.setRippleStyles(true); if(window.requestAnimationFrame) window.requestAnimationFrame(this.animFrameHandler.bind(this)); } }; /** * Handle mouse / finger up on element. * * @param {Event} event The event that fired. * @private */ URipple.prototype._up = function(event) { if (u.isIE8) return; var self = this; // Don't fire for the artificial "mouseup" generated by a double-click. if (event && event.detail !== 2) { u.removeClass(this._rippleElement,'is-visible') } // Allow a repaint to occur before removing this class, so the animation // shows for tap events, which seem to trigger a mouseup too soon after // mousedown. window.setTimeout(function() { u.removeClass(self._rippleElement,'is-visible') }, 0); }; /** * Getter for frameCount_. * @return {number} the frame count. */ URipple.prototype.getFrameCount = function() { if (u.isIE8) return; return this.frameCount_; }; /** * Setter for frameCount_. * @param {number} fC the frame count. */ URipple.prototype.setFrameCount = function(fC) { if (u.isIE8) return; this.frameCount_ = fC; }; /** * Getter for _rippleElement. * @return {Element} the ripple element. */ URipple.prototype.getRippleElement = function() { if (u.isIE8) return; return this._rippleElement; }; /** * Sets the ripple X and Y coordinates. * @param {number} newX the new X coordinate * @param {number} newY the new Y coordinate */ URipple.prototype.setRippleXY = function(newX, newY) { if (u.isIE8) return; this.x_ = newX; this.y_ = newY; }; /** * Sets the ripple styles. * @param {boolean} start whether or not this is the start frame. */ URipple.prototype.setRippleStyles = function(start) { if (u.isIE8) return; if (this._rippleElement !== null) { var transformString; var scale; var size; var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)'; if (start) { scale = 'scale(0.0001, 0.0001)'; size = '1px'; } else { scale = ''; size = this.rippleSize_ + 'px'; } transformString = 'translate(-50%, -50%) ' + offset + scale; this._rippleElement.style.webkitTransform = transformString; this._rippleElement.style.msTransform = transformString; this._rippleElement.style.transform = transformString; if (start) { u.removeClass(this._rippleElement,'is-animating') } else { u.addClass(this._rippleElement,'is-animating') } } }; /** * Handles an animation frame. */ URipple.prototype.animFrameHandler = function() { if (u.isIE8) return; if (this.frameCount_-- > 0) { window.requestAnimationFrame(this.animFrameHandler.bind(this)); } else { this.setRippleStyles(false); } }; /** * Initialize element. */ URipple.prototype.init = function() { if (u.isIE8) return; var self = this; if (this._element) { this._rippleElement = this._element.querySelector('.u-ripple'); if (!this._rippleElement){ this._rippleElement = document.createElement('span'); u.addClass(this._rippleElement,'u-ripple'); this._element.appendChild(this._rippleElement); this._element.style.overflow = 'hidden'; this._element.style.position = 'relative'; } this.frameCount_ = 0; this.rippleSize_ = 0; this.x_ = 0; this.y_ = 0; // Touch start produces a compat mouse down event, which would cause a // second ripples. To avoid that, we use this property to ignore the first // mouse down after a touch start. this._ignoringMouseDown = false; u.on(this._element, 'mousedown',function(e){self._down(e);}) u.on(this._element, 'touchstart',function(e){self._down(e);}) u.on(this._element, 'mouseup',function(e){self._up(e);}) u.on(this._element, 'mouseleave',function(e){self._up(e);}) u.on(this._element, 'touchend',function(e){self._up(e);}) u.on(this._element, 'blur',function(e){self._up(e);}) } }; u.Ripple = URipple;