UNPKG

react-paper-ripple

Version:

Paper ripple animations inspired by Google Material Design.

257 lines (215 loc) 8.97 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _reactDocumentEvents = require('react-document-events'); var _reactDocumentEvents2 = _interopRequireDefault(_reactDocumentEvents); var _reactMotion = require('react-motion'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var eventTypes = { mousedown: 'MouseDown', touchstart: 'touchStart' }; var waveContainerStyles = { position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, overflow: 'hidden' }; function preventDefault(e) { e.preventDefault(); } function Wave(_ref) { var data = _ref.data, _ref$style = _ref.style, scale = _ref$style.scale, opacity = _ref$style.opacity; return _react2.default.createElement('div', { className: 'paper-ripple-wave', style: _extends({}, data, { WebkitTransform: 'scale(' + scale + ', ' + scale + ')', transform: 'scale3d(' + scale + ', ' + scale + ', 1)', opacity: opacity }) }); } var PaperRipple = function (_Component) { _inherits(PaperRipple, _Component); function PaperRipple() { var _ref2; var _temp, _this, _ret; _classCallCheck(this, PaperRipple); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref2 = PaperRipple.__proto__ || Object.getPrototypeOf(PaperRipple)).call.apply(_ref2, [this].concat(args))), _this), _this.state = { waves: [] }, _this._willLeave = function () { var rmConfig = _this.props.rmConfig; return { scale: (0, _reactMotion.spring)(1, rmConfig), opacity: (0, _reactMotion.spring)(0, rmConfig) }; }, _this._addWave = function (e) { if (_this._waveAdded) return; var _this$props = _this.props, growRatio = _this$props.growRatio, center = _this$props.center, color = _this$props.color, rmConfig = _this$props.rmConfig; var key = Date.now().toString(); var waves = [].concat(_toConsumableArray(_this.state.waves)); var rect = _this._parentNode.getBoundingClientRect(); var offsetTop = rect.top + (window ? window.pageYOffset : 0); var offsetLeft = rect.left + (window ? window.pageXOffset : 0); var size = Math.max(rect.width, rect.height) * growRatio; var halfSize = size / 2; var data = { width: size, height: size, backgroundColor: color, borderRadius: '100%', position: 'absolute', pointerEvents: 'none' }; _this._waveAdded = true; _this._currentKey = key; if (center) { data.top = rect.height / 2; data.left = rect.width / 2; data.marginTop = -halfSize; data.marginLeft = -halfSize; } else { var _ref3 = e.touches && e.touches[0] || e, pageX = _ref3.pageX, pageY = _ref3.pageY; data.top = pageY - offsetTop - halfSize; data.left = pageX - offsetLeft - halfSize; } waves.push({ key: key, data: data, style: { scale: (0, _reactMotion.spring)(1, rmConfig), opacity: (0, _reactMotion.spring)(1, rmConfig) } }); _this.setState({ waves: waves }); }, _this._removeWave = function () { if (_this._waveAdded) { _this.setState({ waves: _this.state.waves.filter(function (wave) { return wave.key !== _this._currentKey; }) }); _this._waveAdded = false; } }, _this._handleEvent = function (e) { var eventType = eventTypes[e.type]; var propEvent = _this.props['on' + eventType]; _this._addWave(e); if (typeof propEvent === 'function') { propEvent(e); } }, _this._handleRef = function (node) { _this._parentNode = node && node.parentNode; }, _temp), _possibleConstructorReturn(_this, _ret); } _createClass(PaperRipple, [{ key: 'componentDidMount', value: function componentDidMount() { if (this.props.filled) { this._addWave(); } } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { if (!this.props.filled && nextProps.filled) { this._addWave(); } else if (this.props.filled && !nextProps.filled) { this._removeWave(); } } }, { key: '_willEnter', value: function _willEnter() { return { scale: 0, opacity: 1 }; } }, { key: 'render', value: function render() { var _this2 = this; var _props = this.props, center = _props.center, color = _props.color, growRatio = _props.growRatio, opacity = _props.opacity, filled = _props.filled, rmConfig = _props.rmConfig, restProps = _objectWithoutProperties(_props, ['center', 'color', 'growRatio', 'opacity', 'filled', 'rmConfig']); return _react2.default.createElement( _reactMotion.TransitionMotion, { styles: this.state.waves, willEnter: this._willEnter, willLeave: this._willLeave }, function (interpolatedWaves) { return _react2.default.createElement( 'div', _extends({ ref: _this2._handleRef, className: 'paper-ripple', style: _extends({}, waveContainerStyles, { opacity: opacity }), onMouseDown: _this2._handleEvent, onTouchStart: _this2._handleEvent }, restProps), interpolatedWaves.map(function (config) { return _react2.default.createElement(Wave, config); }), _react2.default.createElement(_reactDocumentEvents2.default, { onMouseup: _this2._removeWave, onTouchEnd: _this2._removeWave, onTouchCancel: _this2._removeWave }) ); } ); } }]); return PaperRipple; }(_react.Component); PaperRipple.propTypes = { center: _propTypes2.default.bool, color: _propTypes2.default.string, opacity: _propTypes2.default.number, growRatio: _propTypes2.default.number, filled: _propTypes2.default.bool, rmConfig: _propTypes2.default.objectOf(_propTypes2.default.number) }; PaperRipple.defaultProps = { center: false, color: '#fff', opacity: 0.25, growRatio: 2.25, filled: null, rmConfig: { stiffness: 100, damping: 20 } }; exports.default = PaperRipple;