generator-bingo-dig-h5
Version:
Bingo-dig-h5 generator by BINGO.DIG
180 lines (152 loc) • 4.19 kB
JSX
var React = require('react');
var Classable = require('../../mixins/classable');
var Dom = require('../../utils/dom');
var RippleCircle = require('./circle');
var TouchRipple = React.createClass({
mixins: [Classable],
propTypes: {
centerRipple: React.PropTypes.bool,
className: React.PropTypes.string
},
getInitialState: function() {
return {
ripples: [{
key: 0,
started: false,
ending: false
}]
};
},
render: function() {
var classes = this.getClasses('dig-touch-ripple');
return (
<div
onMouseUp={this._handleMouseUp}
onMouseDown={this._handleMouseDown}
onMouseOver={this._handleMouseOver}
onMouseOut={this._handleMouseOut}
onTouchStart={this._handleTouchStart}
onTouchEnd={this._handleTouchEnd}>
<div className={classes}>
{this._getRippleElements()}
</div>
{this.props.children}
</div>
);
},
start: function(e) {
var ripples = this.state.ripples;
var nextKey = ripples[ripples.length-1].key + 1;
var style = !this.props.centerRipple ? this._getRippleStyle(e) : {};
var ripple;
//Start the next unstarted ripple
for (var i = 0; i < ripples.length; i++) {
ripple = ripples[i];
if (!ripple.started) {
ripple.started = true;
ripple.style = style;
break;
}
};
//Add an unstarted ripple at the end
ripples.push({
key: nextKey,
started: false,
ending: false
});
//Re-render
this.setState({
ripples: ripples
});
},
end: function() {
var ripples = this.state.ripples;
var ripple;
var endingRipple;
//End the the next un-ended ripple
for (var i = 0; i < ripples.length; i++) {
ripple = ripples[i];
if (ripple.started && !ripple.ending) {
ripple.ending = true;
endingRipple = ripple;
break;
}
};
//Only update if a ripple was found
if (endingRipple) {
//Re-render
this.setState({
ripples: ripples
});
//Wait 2 seconds and remove the ripple from DOM
setTimeout(function() {
ripples.shift();
if (this.isMounted()) {
this.setState({
ripples: ripples
});
}
}.bind(this), 2000);
}
},
_handleMouseDown: function(e) {
//only listen to left clicks
if (e.button === 0) this.start(e);
},
_handleMouseUp: function(e) {
this.end();
},
_handleMouseOver: function(e) {
//this.start(e);
},
_handleMouseOut: function(e) {
this.end();
},
_handleTouchStart: function(e) {
this.start(e);
},
_handleTouchEnd: function(e) {
this.end();
},
_getRippleStyle: function(e) {
var style = {};
var el = this.getDOMNode();
var elHeight = el.offsetHeight;
var elWidth = el.offsetWidth;
var offset = Dom.offset(el);
var pageX = e.pageX == undefined ? e.nativeEvent.pageX : e.pageX;
var pageY = e.pageY == undefined ? e.nativeEvent.pageY : e.pageY;
var pointerX = pageX - offset.left;
var pointerY = pageY - offset.top;
var topLeftDiag = this._calcDiag(pointerX, pointerY);
var topRightDiag = this._calcDiag(elWidth - pointerX, pointerY);
var botRightDiag = this._calcDiag(elWidth - pointerX, elHeight - pointerY);
var botLeftDiag = this._calcDiag(pointerX, elHeight - pointerY);
var rippleRadius = Math.max(
topLeftDiag, topRightDiag, botRightDiag, botLeftDiag
);
var rippleSize = rippleRadius * 2;
var left = pointerX - rippleRadius;
var top = pointerY - rippleRadius;
style.height = rippleSize + 'px';
style.width = rippleSize + 'px';
style.top = top + 'px';
style.left = left + 'px';
return style;
},
_calcDiag: function(a, b) {
return Math.sqrt((a * a) + (b * b));
},
_getRippleElements: function() {
return this.state.ripples.map(function (ripple) {
return (
<RippleCircle
key={ripple.key}
started={ripple.started}
ending={ripple.ending}
style={ripple.style} />
);
}.bind(this));
}
});
module.exports = TouchRipple;