UNPKG

rc-tween-one

Version:
297 lines (258 loc) 10.7 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _TweenOne = require('./TweenOne'); var _TweenOne2 = _interopRequireDefault(_TweenOne); var _util = require('./util'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function noop() {} var TweenOneGroup = function (_Component) { (0, _inherits3['default'])(TweenOneGroup, _Component); function TweenOneGroup(props) { (0, _classCallCheck3['default'])(this, TweenOneGroup); var _this = (0, _possibleConstructorReturn3['default'])(this, (TweenOneGroup.__proto__ || Object.getPrototypeOf(TweenOneGroup)).call(this, props)); _initialiseProps.call(_this); _this.keysToEnter = []; _this.keysToLeave = []; _this.saveTweenTag = {}; _this.onEnterBool = false; _this.animQueue = []; _this.isTween = {}; // 第一进入,appear 为 true 时默认用 enter 或 tween-one 上的效果 var children = (0, _util.toArrayChildren)((0, _util.getChildrenFromProps)(_this.props)); _this.originalChildren = (0, _util.toArrayChildren)((0, _util.getChildrenFromProps)(_this.props)); _this.currentChildren = (0, _util.toArrayChildren)((0, _util.getChildrenFromProps)(_this.props)); _this.state = { children: children }; return _this; } (0, _createClass3['default'])(TweenOneGroup, [{ key: 'componentDidMount', value: function componentDidMount() { this.onEnterBool = true; } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { var nextChildren = (0, _util.toArrayChildren)(nextProps.children); if (Object.keys(this.isTween).length && !nextProps.exclusive) { this.animQueue.push(nextChildren); return; } var currentChildren = (0, _util.toArrayChildren)(nextProps.exclusive ? this.originalChildren : this.state.children); this.changeChildren(nextChildren, currentChildren); } }, { key: 'componentDidUpdate', value: function componentDidUpdate() { this.originalChildren = (0, _util.toArrayChildren)((0, _util.getChildrenFromProps)(this.props)); } }, { key: 'changeChildren', value: function changeChildren(nextChildren, currentChildren) { var _this2 = this; var newChildren = (0, _util.mergeChildren)(currentChildren, nextChildren); this.keysToEnter = []; this.keysToLeave = []; nextChildren.forEach(function (c) { if (!c) { return; } var key = c.key; var hasPrev = (0, _util.findChildInChildrenByKey)(currentChildren, key); // 如果当前 key 已存在 saveTweenTag 里,,刷新 child; if (_this2.saveTweenTag[key]) { _this2.saveTweenTag[key] = _react2['default'].cloneElement(_this2.saveTweenTag[key], {}, c); } if (!hasPrev && key) { _this2.keysToEnter.push(key); } }); currentChildren.forEach(function (c) { if (!c) { return; } var key = c.key; var hasNext = (0, _util.findChildInChildrenByKey)(nextChildren, key); if (!hasNext && key) { _this2.keysToLeave.push(key); delete _this2.saveTweenTag[key]; } }); this.currentChildren = newChildren; this.setState({ children: newChildren }); } }, { key: 'render', value: function render() { var childrenToRender = this.getChildrenToRender(this.state.children); if (!this.props.component) { return childrenToRender[0] || null; } var componentProps = (0, _extends3['default'])({}, this.props); ['component', 'componentProps', 'appear', 'enter', 'leave', 'animatingClassName', 'onEnd', 'exclusive'].forEach(function (key) { return delete componentProps[key]; }); return (0, _react.createElement)(this.props.component, (0, _extends3['default'])({}, componentProps, this.props.componentProps), childrenToRender); } }]); return TweenOneGroup; }(_react.Component); var _initialiseProps = function _initialiseProps() { var _this3 = this; this.onChange = function (animation, key, type, obj) { var length = (0, _util.dataToArray)(animation).length; var tag = obj.target; var classIsSvg = typeof tag.className === 'object' && 'baseVal' in tag.className; var isEnter = type === 'enter' || type === 'appear'; if (obj.mode === 'onStart') { if (classIsSvg) { tag.className.baseVal = _this3.setClassName(tag.className.baseVal, isEnter); } else { tag.className = _this3.setClassName(tag.className, isEnter); } } else if (obj.index === length - 1 && obj.mode === 'onComplete') { delete _this3.isTween[key]; if (classIsSvg) { tag.className.baseVal = tag.className.baseVal.replace(_this3.props.animatingClassName[isEnter ? 0 : 1], '').trim(); } else { tag.className = tag.className.replace(_this3.props.animatingClassName[isEnter ? 0 : 1], '').trim(); } if (type === 'enter') { _this3.keysToEnter.splice(_this3.keysToEnter.indexOf(key), 1); if (!_this3.keysToEnter.length) { _this3.reAnimQueue(); } } else if (type === 'leave') { _this3.keysToLeave.splice(_this3.keysToLeave.indexOf(key), 1); _this3.currentChildren = _this3.currentChildren.filter(function (child) { return key !== child.key; }); if (!_this3.keysToLeave.length) { var currentChildrenKeys = _this3.currentChildren.map(function (item) { return item.key; }); Object.keys(_this3.saveTweenTag).forEach(function ($key) { if (currentChildrenKeys.indexOf($key) === -1) { delete _this3.saveTweenTag[$key]; } }); _this3.setState({ children: _this3.currentChildren }, _this3.reAnimQueue); } } var _obj = { key: key, type: type }; _this3.props.onEnd(_obj); } }; this.setClassName = function (name, isEnter) { var className = name.replace(_this3.props.animatingClassName[isEnter ? 1 : 0], '').trim(); if (className.indexOf(_this3.props.animatingClassName[isEnter ? 0 : 1]) === -1) { className = (className + ' ' + _this3.props.animatingClassName[isEnter ? 0 : 1]).trim(); } return className; }; this.getTweenChild = function (child) { var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var key = child.key; _this3.saveTweenTag[key] = _react2['default'].createElement(_TweenOne2['default'], (0, _extends3['default'])({}, props, { key: key, component: null }), child); return _this3.saveTweenTag[key]; }; this.getCoverAnimation = function (child, i, type) { var animation = void 0; animation = type === 'leave' ? _this3.props.leave : _this3.props.enter; if (type === 'appear') { var appear = (0, _util.transformArguments)(_this3.props.appear, child.key, i); animation = appear && _this3.props.enter || null; } var animate = (0, _util.transformArguments)(animation, child.key, i); var onChange = _this3.onChange.bind(_this3, animate, child.key, type); var props = { key: child.key, animation: animate, onChange: onChange, resetStyle: _this3.props.exclusive }; if (_this3.keysToEnter.concat(_this3.keysToLeave).indexOf(child.key) >= 0 || !_this3.onEnterBool && animation) { if (!_this3.saveTweenTag[child.key]) { _this3.isTween[child.key] = type; } } var children = _this3.getTweenChild(child, props); return children; }; this.getChildrenToRender = function (children) { return children.map(function (child, i) { if (!child || !child.key) { return child; } var key = child.key; if (_this3.keysToLeave.indexOf(key) >= 0) { return _this3.getCoverAnimation(child, i, 'leave'); } else if ((_this3.keysToEnter.indexOf(key) >= 0 || _this3.isTween[key] && _this3.keysToLeave.indexOf(key) === -1) && !(_this3.isTween[key] === 'enter' && _this3.saveTweenTag[key])) { /** * 1. 在 key 在 enter 里。 * 2. 出场未结束,触发进场, this.isTween[key] 为 leave, key 在 enter 里。 * 3. 状态为 enter 且 tweenTag 里有值时,不执行重载动画属性,直接调用 tweenTag 里的。 */ return _this3.getCoverAnimation(child, i, 'enter'); } else if (!_this3.onEnterBool) { return _this3.getCoverAnimation(child, i, 'appear'); } return _this3.saveTweenTag[key]; }); }; this.reAnimQueue = function () { if (!Object.keys(_this3.isTween).length && _this3.animQueue.length) { _this3.changeChildren(_this3.animQueue[_this3.animQueue.length - 1], _this3.state.children); _this3.animQueue = []; } }; }; TweenOneGroup.propTypes = { component: _propTypes2['default'].any, componentProps: _propTypes2['default'].object, children: _propTypes2['default'].any, style: _propTypes2['default'].object, appear: _propTypes2['default'].bool, enter: _propTypes2['default'].any, leave: _propTypes2['default'].any, animatingClassName: _propTypes2['default'].array, onEnd: _propTypes2['default'].func, exclusive: _propTypes2['default'].bool }; TweenOneGroup.defaultProps = { component: 'div', componentProps: {}, appear: true, animatingClassName: ['tween-one-entering', 'tween-one-leaving'], enter: { x: 50, opacity: 0, type: 'from' }, leave: { x: -50, opacity: 0 }, onEnd: noop, exclusive: false }; TweenOneGroup.isTweenOneGroup = true; exports['default'] = TweenOneGroup; module.exports = exports['default'];