iuap-design
Version:
UI Framework Used For Enterprise.
199 lines (173 loc) • 6.32 kB
JavaScript
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;