UNPKG

rc-tween-one

Version:
288 lines (237 loc) 10.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _react = _interopRequireWildcard(require("react")); var _group = require("./utils/group"); var _common = require("./utils/common"); var _TweenOne = _interopRequireDefault(require("./TweenOne")); var _excluded = ["component", "componentProps", "leave", "enter", "appear", "resetStyle", "animatingClassName", "onEnd", "exclusive"]; var TweenOneGroup = /*#__PURE__*/_react.default.forwardRef(function (props, ref) { var _props$component = props.component, component = _props$component === void 0 ? 'div' : _props$component, _props$componentProps = props.componentProps, componentProps = _props$componentProps === void 0 ? {} : _props$componentProps, _props$leave = props.leave, leaveAnim = _props$leave === void 0 ? { x: -50, opacity: 0 } : _props$leave, _props$enter = props.enter, enterAnim = _props$enter === void 0 ? { x: 50, opacity: 0, type: 'from' } : _props$enter, _props$appear = props.appear, appearBool = _props$appear === void 0 ? true : _props$appear, _props$resetStyle = props.resetStyle, resetStyle = _props$resetStyle === void 0 ? true : _props$resetStyle, _props$animatingClass = props.animatingClassName, animatingClassName = _props$animatingClass === void 0 ? ['tween-one-entering', 'tween-one-leaving'] : _props$animatingClass, _props$onEnd = props.onEnd, onEnd = _props$onEnd === void 0 ? function () {} : _props$onEnd, _props$exclusive = props.exclusive, exclusive = _props$exclusive === void 0 ? false : _props$exclusive, tagProps = (0, _objectWithoutProperties2.default)(props, _excluded); var keysToEnter = (0, _react.useRef)([]); var keysToLeave = (0, _react.useRef)([]); var saveTweenTag = (0, _react.useRef)({}); var oneEnter = (0, _react.useRef)(false); var animQueue = (0, _react.useRef)([]); var isTween = (0, _react.useRef)({}); var cChild = (0, _group.toArrayChildren)((0, _group.getChildrenFromProps)(props)); var currentChildren = (0, _react.useRef)(cChild); var _useState = (0, _react.useState)(cChild), _useState2 = (0, _slicedToArray2.default)(_useState, 2), children = _useState2[0], setChild = _useState2[1]; var getTweenChild = function getTweenChild(child) { var p = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var key = child.key; saveTweenTag.current[key] = /*#__PURE__*/_react.default.createElement(_TweenOne.default, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, p), {}, { key: key, component: null }), child); return saveTweenTag.current[key]; }; var setClassName = function setClassName(name, isEnter) { var className = name.replace(animatingClassName[isEnter ? 1 : 0], '').trim(); if (className.indexOf(animatingClassName[isEnter ? 0 : 1]) === -1) { className = "".concat(className, " ").concat(animatingClassName[isEnter ? 0 : 1]).trim(); } return className; }; var changeChildren = function changeChildren(nextChildren, currentChild) { var newChildren = (0, _group.mergeChildren)(currentChild, nextChildren); keysToEnter.current = []; keysToLeave.current = []; nextChildren.forEach(function (c) { if (!c) { return; } var key = c.key; var hasPrev = (0, _group.findChildInChildrenByKey)(currentChild, key); // 如果当前 key 已存在 saveTweenTag 里,,刷新 child; if (key && saveTweenTag.current[key]) { saveTweenTag.current[key] = /*#__PURE__*/_react.default.cloneElement(saveTweenTag.current[key], {}, c); } if (!hasPrev && key) { keysToEnter.current.push(key); } }); currentChild.forEach(function (c) { if (!c) { return; } var key = c.key; var hasNext = (0, _group.findChildInChildrenByKey)(nextChildren, key); if (!hasNext && key) { keysToLeave.current.push(key); delete saveTweenTag.current[key]; } }); return newChildren; }; var reAnimQueue = function reAnimQueue() { if (!Object.keys(isTween.current).length && animQueue.current.length) { // 取最后一个继续动画; var child = changeChildren(animQueue.current[animQueue.current.length - 1], currentChildren.current); setChild(child); animQueue.current = []; } }; var onChange = function onChange(key, type, obj) { var tag = obj.targets; var classIsSvg = (0, _typeof2.default)(tag.className) === 'object' && 'baseVal' in tag.className; var isEnter = type === 'enter' || type === 'appear'; if (key && obj.mode === 'onTimelineComplete') { delete isTween.current[key]; if (classIsSvg) { tag.className.baseVal = tag.className.baseVal.replace(animatingClassName[isEnter ? 0 : 1], '').trim(); } else { tag.className = tag.className.replace(animatingClassName[isEnter ? 0 : 1], '').trim(); } if (isEnter) { keysToEnter.current.splice(keysToEnter.current.indexOf(key), 1); if (!keysToEnter.current.length) { // enter 不会触发 did update, 手动触发一次; reAnimQueue(); } } else if (type === 'leave') { keysToLeave.current.splice(keysToLeave.current.indexOf(key), 1); currentChildren.current = currentChildren.current.filter(function (child) { return key !== child.key; }); if (!keysToLeave.current.length) { var currentChildrenKeys = currentChildren.current.map(function (item) { return item.key; }); Object.keys(saveTweenTag.current).forEach(function ($key) { if (currentChildrenKeys.indexOf($key) === -1) { delete saveTweenTag.current[$key]; } }); setChild(currentChildren.current); } } onEnd({ key: key, type: type, target: obj.targets }); } }; var getCoverAnimation = function getCoverAnimation(child, i, type) { var animation = type === 'leave' ? leaveAnim : enterAnim; if (type === 'appear') { var appear = (0, _group.transformArguments)(appearBool, child.key, i); animation = appear && enterAnim || null; } var animate = (0, _group.transformArguments)(animation, child.key, i); var onChangeCb = function onChangeCb(obj) { onChange(child.key, type, obj); }; var className = type === 'appear' && !appearBool ? child.props.className : setClassName(child.props.className || '', type === 'enter' || type === 'appear') || undefined; var p = { key: child.key, animation: animate, onChangeTimeline: onChangeCb, resetStyle: resetStyle, className: className }; if (child.key && keysToEnter.current.concat(keysToLeave.current).indexOf(child.key) >= 0 || !oneEnter.current && animation) { if (child.key && !saveTweenTag.current[child.key]) { isTween.current[child.key] = type; } } return getTweenChild(child, p); }; (0, _common.useIsomorphicLayoutEffect)(function () { if (oneEnter.current) { var nextChild = (0, _group.toArrayChildren)(props.children).filter(function (c) { return c; }); var currentChild = (0, _group.toArrayChildren)(currentChildren.current); // 如果还在动画,暂存动画队列里,等前一次动画结束后再启动最后次的更新动画 if (Object.keys(isTween.current).length && !exclusive) { animQueue.current.push(nextChild); } else { setChild(changeChildren(nextChild, currentChild)); } } }, [props.children]); (0, _common.useIsomorphicLayoutEffect)(function () { reAnimQueue(); }); (0, _react.useEffect)(function () { oneEnter.current = true; }, []); currentChildren.current = children; var childrenToRender = children.map(function (child, i) { if (!child || !child.key) { return child; } var key = child.key; if (keysToLeave.current.indexOf(key) >= 0) { return getCoverAnimation(child, keysToLeave.current.indexOf(key), 'leave'); } if ((keysToEnter.current.indexOf(key) >= 0 || isTween.current[key] && keysToLeave.current.indexOf(key) === -1) && !(isTween.current[key] === 'enter' && saveTweenTag.current[key])) { /** * 1. 在 key 在 enter 里。 * 2. 出场未结束,触发进场, this.isTween[key] 为 leave, key 在 enter 里。 * 3. 状态为 enter 且 tweenTag 里有值时,不执行重载动画属性,直接调用 tweenTag 里的。 */ return getCoverAnimation(child, keysToEnter.current.indexOf(key), 'enter'); } if (!oneEnter.current) { return getCoverAnimation(child, i, 'appear'); } return saveTweenTag.current[key]; }); if (_common.windowIsUndefined) { if (!component) { return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, props.children); } return /*#__PURE__*/(0, _react.createElement)(component, (0, _objectSpread2.default)((0, _objectSpread2.default)((0, _objectSpread2.default)({}, tagProps), componentProps), {}, { ref: ref }), props.children); } if (!component) { return childrenToRender[0] ? /*#__PURE__*/(0, _react.cloneElement)(childrenToRender[0], { ref: ref }) : null; } return /*#__PURE__*/(0, _react.createElement)(component, (0, _objectSpread2.default)((0, _objectSpread2.default)((0, _objectSpread2.default)({}, tagProps), componentProps), {}, { ref: ref }), childrenToRender); }); TweenOneGroup.displayName = 'TweenOneGroup'; TweenOneGroup.isTweenOneGroup = true; var _default = TweenOneGroup; exports.default = _default;