UNPKG

rc-tween-one

Version:
382 lines (331 loc) 12.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 _reactDom = require('react-dom'); var _reactDom2 = _interopRequireDefault(_reactDom); var _util = require('./util'); var _Tween = require('./Tween'); var _Tween2 = _interopRequireDefault(_Tween); var _ticker = require('./ticker'); var _ticker2 = _interopRequireDefault(_ticker); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function noop() {} var perFrame = Math.round(1000 / 60); var objectOrArray = _propTypes2['default'].oneOfType([_propTypes2['default'].object, _propTypes2['default'].array]); var TweenOne = function (_Component) { (0, _inherits3['default'])(TweenOne, _Component); function TweenOne(props) { (0, _classCallCheck3['default'])(this, TweenOne); var _this = (0, _possibleConstructorReturn3['default'])(this, (TweenOne.__proto__ || Object.getPrototypeOf(TweenOne)).call(this, props)); _initialiseProps.call(_this); _this.rafID = -1; _this.setDefalut(props); _this.paused = props.paused; _this.reverse = props.reverse; _this.updateAnim = false; _this.forced = {}; _this.setForcedJudg(props); return _this; } (0, _createClass3['default'])(TweenOne, [{ key: 'componentDidMount', value: function componentDidMount() { this.dom = _reactDom2['default'].findDOMNode(this); if (this.dom && this.dom.nodeName !== '#text') { this.start(); } } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { if (!this.tween && !this.dom) { this.updateAnim = true; return; } // 动画处理 var newAnimation = nextProps.animation; var currentAnimation = this.props.animation; var equal = (0, _util.objectEqual)(currentAnimation, newAnimation); if (!equal) { if (nextProps.resetStyle && this.tween) { this.tween.resetDefaultStyle(); } this.setDefalut(nextProps); this.updateAnim = true; } // 跳帧事件 moment; var nextMoment = nextProps.moment; if (typeof nextMoment === 'number' && nextMoment !== this.props.moment) { if (this.tween && !this.updateAnim) { this.startMoment = nextMoment; this.startFrame = _ticker2['default'].frame; if (nextProps.paused) { this.raf(); } if (this.tween.progressTime >= this.tween.totalTime) { this.play(); } } else { this.setDefalut(nextProps); this.updateAnim = true; } } // 暂停倒放 if (this.paused !== nextProps.paused || this.reverse !== nextProps.reverse) { this.paused = nextProps.paused; this.reverse = nextProps.reverse; if (this.paused) { this.cancelRequestAnimationFrame(); } else if (this.reverse && nextProps.reverseDelay) { this.cancelRequestAnimationFrame(); _ticker2['default'].timeout(this.restart, nextProps.reverseDelay); } else { // 在 form 状态下,暂停时拉 moment 时,start 有值恢复播放,在 delay 的时间没有处理。。 if (this.tween) { this.tween.resetAnimData(); this.tween.resetDefaultStyle(); } if (!this.updateAnim) { this.restart(); } } } var styleEqual = (0, _util.objectEqual)(this.props.style, nextProps.style); if (!styleEqual) { // 在动画时更改了 style, 作为更改开始数值。 if (this.tween) { this.tween.reStart(nextProps.style); if (this.paused) { this.raf(); } } } this.setForcedJudg(nextProps); } }, { key: 'componentDidUpdate', value: function componentDidUpdate() { if (!this.dom) { this.dom = _reactDom2['default'].findDOMNode(this); } // 样式更新了后再执行动画; if (this.updateAnim && this.dom && this.dom.nodeName !== '#text') { if (this.tween) { this.cancelRequestAnimationFrame(); } this.start(); } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { this.cancelRequestAnimationFrame(); } /** * @method setForcedJudg * @param props * QueueAnim 套在组件下面后导至子级变化。 * <QueueAnim component={Menu} > * <SubMenu key="a" title="导航"> * <Item /> * </SubMenu> * </QueueAnim> * rc-Menu 里是以 isXXX 来判断是 rc-Menu 的子级; * 如: 用 isSubMenu 来处理 hover 事件 * 地址: https://github.com/react-component/menu/blob/master/src/MenuMixin.js#L172 * 暂时方案: 在组件里添加判断用的值。 */ }, { key: 'render', value: function render() { var props = (0, _extends3['default'])({}, this.props); ['animation', 'component', 'componentProps', 'reverseDelay', 'attr', 'paused', 'reverse', 'repeat', 'yoyo', 'moment', 'resetStyle', 'forcedJudg'].forEach(function (key) { return delete props[key]; }); props.style = (0, _extends3['default'])({}, this.props.style); Object.keys(props.style).forEach(function (p) { if (p.match(/filter/i)) { ['Webkit', 'Moz', 'Ms', 'ms'].forEach(function (prefix) { props.style[prefix + 'Filter'] = props.style[p]; }); } }); // component 为空时调用子级的。。 if (!this.props.component) { if (!this.props.children) { return this.props.children; } var childrenProps = this.props.children.props; var style = childrenProps.style, className = childrenProps.className; // 合并 style 与 className。 var newStyle = (0, _extends3['default'])({}, style, props.style); var newClassName = props.className ? props.className + ' ' + className : className; return _react2['default'].cloneElement(this.props.children, { style: newStyle, className: newClassName }); } return _react2['default'].createElement(this.props.component, (0, _extends3['default'])({}, props, this.props.componentProps)); } }]); return TweenOne; }(_react.Component); TweenOne.propTypes = { component: _propTypes2['default'].any, componentProps: _propTypes2['default'].any, animation: objectOrArray, children: _propTypes2['default'].any, style: _propTypes2['default'].object, paused: _propTypes2['default'].bool, reverse: _propTypes2['default'].bool, reverseDelay: _propTypes2['default'].number, yoyo: _propTypes2['default'].bool, repeat: _propTypes2['default'].number, moment: _propTypes2['default'].number, attr: _propTypes2['default'].string, onChange: _propTypes2['default'].func, resetStyle: _propTypes2['default'].bool, forcedJudg: _propTypes2['default'].object }; TweenOne.defaultProps = { component: 'div', componentProps: {}, reverseDelay: 0, repeat: 0, attr: 'style', onChange: noop }; var _initialiseProps = function _initialiseProps() { var _this2 = this; this.setForcedJudg = function (props) { Object.keys(_this2.forced).forEach(function (key) { delete _this2[key]; delete _this2.forced[key]; }); if (props.forcedJudg) { Object.keys(props.forcedJudg).forEach(function (key) { if (!_this2[key]) { _this2[key] = props.forcedJudg[key]; _this2.forced[key] = 1; } }); } }; this.setDefalut = function (props) { _this2.moment = props.moment || 0; _this2.startMoment = props.moment || 0; _this2.startFrame = _ticker2['default'].frame; }; this.restart = function () { if (!_this2.tween) { return; } _this2.startMoment = _this2.moment; _this2.startFrame = _ticker2['default'].frame; _this2.tween.reverse = _this2.reverse; _this2.tween.reverseStartTime = _this2.startMoment; _this2.raf(); _this2.play(); }; this.start = function () { _this2.updateAnim = false; var props = _this2.props; if (props.animation && Object.keys(props.animation).length) { _this2.tween = new _Tween2['default'](_this2.dom, (0, _util.dataToArray)(props.animation), { attr: props.attr }); _this2.tween.reverse = _this2.reverse; // 预先注册 raf, 初始动画数值。 _this2.raf(); // 开始动画 _this2.play(); } }; this.play = function () { _this2.cancelRequestAnimationFrame(); if (_this2.paused) { return; } _this2.rafID = _ticker2['default'].add(_this2.raf); }; this.frame = function () { var yoyo = _this2.props.yoyo; var repeat = _this2.props.repeat; var totalTime = repeat === -1 ? Number.MAX_VALUE : _this2.tween.totalTime * (repeat + 1); repeat = repeat >= 0 ? repeat : Number.MAX_VALUE; var moment = (_ticker2['default'].frame - _this2.startFrame) * perFrame + _this2.startMoment; if (_this2.reverse) { moment = (_this2.startMoment || 0) - (_ticker2['default'].frame - _this2.startFrame) * perFrame; } moment = moment > totalTime ? totalTime : moment; moment = moment <= 0 ? 0 : moment; var repeatNum = Math.floor(moment / _this2.tween.totalTime) || 0; repeatNum = repeatNum > repeat ? repeat : repeatNum; var tweenMoment = moment - _this2.tween.totalTime * repeatNum; tweenMoment = tweenMoment < perFrame && !_this2.reverse ? 0 : tweenMoment; if (repeat && moment && moment - _this2.tween.totalTime * repeatNum < perFrame) { // 在重置样式之前补 complete; _this2.tween.frame(_this2.tween.totalTime * repeatNum); } if (moment < _this2.moment && !_this2.reverse || repeat !== 0 && repeatNum && tweenMoment <= perFrame) { // 在 form 状态下,暂停时拉 moment 时,start 有值,,往返方向播放时,在 delay 的时间没有处理。。 // 与上面的处理一样,删除 start ,重新走一遍 start。。 _this2.tween.resetAnimData(); _this2.tween.resetDefaultStyle(); } var yoyoReverse = yoyo && repeatNum % 2; if (yoyoReverse) { tweenMoment = _this2.tween.totalTime - tweenMoment; } _this2.tween.onChange = function (e) { var cb = (0, _extends3['default'])({}, e, { timelineMode: '' }); if (!moment && !_this2.reverse || _this2.reverse && _this2.moment === _this2.startMoment) { cb.timelineMode = 'onTimelineStart'; } else if (moment >= totalTime && !_this2.reverse || !moment && _this2.reverse) { cb.timelineMode = 'onTimelineComplete'; } else if (repeatNum !== _this2.timelineRepeatNum) { cb.timelineMode = 'onTimelineRepeat'; } else { cb.timelineMode = 'onTimelineUpdate'; } _this2.props.onChange(cb); }; _this2.moment = moment; _this2.timelineRepeatNum = repeatNum; _this2.tween.frame(tweenMoment); }; this.raf = function () { var tween = _this2.tween; _this2.frame(); if (tween !== _this2.tween) { // 在 onComplete 时更换动画时,raf 没结束,所以需要强制退出,避逸两个时间的冲突。 return null; } var repeat = _this2.props.repeat; var totalTime = repeat === -1 ? Number.MAX_VALUE : _this2.tween.totalTime * (repeat + 1); if (_this2.moment >= totalTime && !_this2.reverse || _this2.paused || _this2.reverse && _this2.moment === 0) { return _this2.cancelRequestAnimationFrame(); } return null; }; this.cancelRequestAnimationFrame = function () { _ticker2['default'].clear(_this2.rafID); _this2.rafID = -1; }; }; TweenOne.isTweenOne = true; exports['default'] = TweenOne; module.exports = exports['default'];