rc-tween-one
Version:
tween-one anim component for react
163 lines (139 loc) • 5.51 kB
JavaScript
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
var _excluded = ["component", "componentProps", "animation", "attr", "paused", "reverse", "repeat", "repeatDelay", "yoyo", "moment", "onChange", "onChangeTimeline", "resetStyle", "killPrevAnim"];
import React, { useRef, createElement, useEffect } from 'react';
import { findDOMNode } from 'react-dom';
import TweenOneJS from 'tween-one';
import { toStyleUpperCase, stylesToCss } from 'style-utils';
import { objectEqual, dataToArray } from './utils';
import { useIsomorphicLayoutEffect } from './utils/common';
var TweenOne = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
var _ref$component = _ref.component,
component = _ref$component === void 0 ? 'div' : _ref$component,
componentProps = _ref.componentProps,
animation = _ref.animation,
attr = _ref.attr,
paused = _ref.paused,
reverse = _ref.reverse,
repeat = _ref.repeat,
repeatDelay = _ref.repeatDelay,
yoyo = _ref.yoyo,
moment = _ref.moment,
onChange = _ref.onChange,
onChangeTimeline = _ref.onChangeTimeline,
resetStyle = _ref.resetStyle,
_ref$killPrevAnim = _ref.killPrevAnim,
killPrevAnim = _ref$killPrevAnim === void 0 ? true : _ref$killPrevAnim,
props = _objectWithoutProperties(_ref, _excluded);
var _ref2 = props || {},
children = _ref2.children,
className = _ref2.className,
_ref2$style = _ref2.style,
style = _ref2$style === void 0 ? {} : _ref2$style;
var domRef = useRef();
var prevAnim = useRef();
var animRef = useRef();
var commonFunc = function commonFunc(key, value) {
var tween = animRef.current;
if (tween) {
if (key === 'moment') {
if (typeof value === 'number') {
tween.goto(value, paused);
}
return;
}
tween[key] = !!value;
}
};
useIsomorphicLayoutEffect(function () {
commonFunc('paused', paused);
}, [paused]); // yoyo, moment, reverse, repeat, repeatDelay
useIsomorphicLayoutEffect(function () {
commonFunc('moment', moment);
}, [moment]);
useIsomorphicLayoutEffect(function () {
commonFunc('reverse', reverse);
}, [reverse]);
useIsomorphicLayoutEffect(function () {
if (!domRef.current) {
return console.warn('Warning: TweenOne domRef is error.');
} // 动画写在标签上,手动对比;
if (!objectEqual(animation, prevAnim.current)) {
var doms = dataToArray(domRef.current).map(function (item) {
return item instanceof Element || !(item instanceof React.Component) ? item : findDOMNode(item);
}).filter(function (item, i) {
if (!(item instanceof Element)) {
console.warn("Warning: TweenOne tag[".concat(i, "] is not dom."));
return false;
}
return item;
});
if (animRef.current && killPrevAnim) {
animRef.current.kill();
}
if (resetStyle && animRef.current) {
var s = !component ? _objectSpread(_objectSpread({}, style), children.props.style) : style;
var styleStr = Object.keys(s).map(function (key) {
return "".concat(toStyleUpperCase(key), ":").concat(stylesToCss(key, s[key]));
}).join(';');
doms.forEach(function (item) {
item.setAttribute('style', styleStr); // dom.style.cssText = styleStr;
delete item._tweenOneVars; // eslint-disable-line no-underscore-dangle
});
}
animRef.current = animation && TweenOneJS(doms, {
animation: animation,
attr: attr,
yoyo: yoyo,
moment: moment,
repeat: repeat,
reverse: reverse,
paused: paused,
repeatDelay: repeatDelay,
onChange: onChange,
onChangeTimeline: onChangeTimeline
});
prevAnim.current = animation;
}
}, [animation]);
useEffect(function () {
return function () {
if (animRef.current && animRef.current.kill) {
animRef.current.kill();
}
};
}, []);
var refFunc = function refFunc(c) {
domRef.current = c;
if (ref && 'current' in ref) {
ref.current = c;
} else if (typeof ref === 'function') {
ref(c);
}
};
if (!component && children && typeof children !== 'string' && typeof children !== 'boolean' && typeof children !== 'number') {
var childrenProps = children.props;
var _ref3 = childrenProps || {},
childStyle = _ref3.style,
_ref3$className = _ref3.className,
childClass = _ref3$className === void 0 ? '' : _ref3$className; // 合并 style 与 className。
var newStyle = _objectSpread(_objectSpread({}, childStyle), style);
var newClassName = className ? "".concat(className, " ").concat(childClass).trim() : childClass;
return /*#__PURE__*/React.cloneElement(children, {
style: newStyle,
ref: refFunc,
className: _toConsumableArray(new Set(newClassName.split(/\s+/))).join(' ').trim() || undefined
});
}
if (!component) {
console.warn('Warning: component is null, children must be ReactElement.');
return children;
}
return /*#__PURE__*/createElement(component, _objectSpread(_objectSpread({
ref: refFunc
}, props), componentProps));
});
TweenOne.isTweenOne = true;
TweenOne.displayName = 'TweenOne';
export default TweenOne;