first commit
This commit is contained in:
336
node_modules/react-smooth/src/Animate.js
generated
vendored
Normal file
336
node_modules/react-smooth/src/Animate.js
generated
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
import React, { PureComponent, cloneElement, Children } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { deepEqual } from 'fast-equals';
|
||||
import createAnimateManager from './AnimateManager';
|
||||
import { configEasing } from './easing';
|
||||
import configUpdate from './configUpdate';
|
||||
import { getTransitionVal, identity } from './util';
|
||||
|
||||
class Animate extends PureComponent {
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
const { isActive, attributeName, from, to, steps, children, duration } = this.props;
|
||||
|
||||
this.handleStyleChange = this.handleStyleChange.bind(this);
|
||||
this.changeStyle = this.changeStyle.bind(this);
|
||||
|
||||
if (!isActive || duration <= 0) {
|
||||
this.state = { style: {} };
|
||||
|
||||
// if children is a function and animation is not active, set style to 'to'
|
||||
if (typeof children === 'function') {
|
||||
this.state = { style: to };
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (steps && steps.length) {
|
||||
this.state = { style: steps[0].style };
|
||||
} else if (from) {
|
||||
if (typeof children === 'function') {
|
||||
this.state = {
|
||||
style: from,
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
this.state = {
|
||||
style: attributeName ? { [attributeName]: from } : from,
|
||||
};
|
||||
} else {
|
||||
this.state = { style: {} };
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { isActive, canBegin } = this.props;
|
||||
|
||||
this.mounted = true;
|
||||
|
||||
if (!isActive || !canBegin) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.runAnimation(this.props);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { isActive, canBegin, attributeName, shouldReAnimate, to, from: currentFrom } = this.props;
|
||||
const { style } = this.state;
|
||||
|
||||
if (!canBegin) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isActive) {
|
||||
const newState = {
|
||||
style: attributeName ? { [attributeName]: to } : to,
|
||||
};
|
||||
if (this.state && style) {
|
||||
if ((attributeName && style[attributeName] !== to) || (!attributeName && style !== to)) {
|
||||
// eslint-disable-next-line react/no-did-update-set-state
|
||||
this.setState(newState);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (deepEqual(prevProps.to, to) && prevProps.canBegin && prevProps.isActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isTriggered = !prevProps.canBegin || !prevProps.isActive;
|
||||
|
||||
if (this.manager) {
|
||||
this.manager.stop();
|
||||
}
|
||||
|
||||
if (this.stopJSAnimation) {
|
||||
this.stopJSAnimation();
|
||||
}
|
||||
|
||||
const from = isTriggered || shouldReAnimate ? currentFrom : prevProps.to;
|
||||
|
||||
if (this.state && style) {
|
||||
const newState = {
|
||||
style: attributeName ? { [attributeName]: from } : from,
|
||||
};
|
||||
if ((attributeName && style[attributeName] !== from) || (!attributeName && style !== from)) {
|
||||
// eslint-disable-next-line react/no-did-update-set-state
|
||||
this.setState(newState);
|
||||
}
|
||||
}
|
||||
|
||||
this.runAnimation({
|
||||
...this.props,
|
||||
from,
|
||||
begin: 0,
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.mounted = false;
|
||||
const { onAnimationEnd } = this.props;
|
||||
|
||||
if (this.unSubscribe) {
|
||||
this.unSubscribe();
|
||||
}
|
||||
|
||||
if (this.manager) {
|
||||
this.manager.stop();
|
||||
this.manager = null;
|
||||
}
|
||||
|
||||
if (this.stopJSAnimation) {
|
||||
this.stopJSAnimation();
|
||||
}
|
||||
|
||||
if (onAnimationEnd) {
|
||||
onAnimationEnd();
|
||||
}
|
||||
}
|
||||
|
||||
handleStyleChange(style) {
|
||||
this.changeStyle(style);
|
||||
}
|
||||
|
||||
changeStyle(style) {
|
||||
if (this.mounted) {
|
||||
this.setState({
|
||||
style,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
runJSAnimation(props) {
|
||||
const { from, to, duration, easing, begin, onAnimationEnd, onAnimationStart } = props;
|
||||
const startAnimation = configUpdate(from, to, configEasing(easing), duration, this.changeStyle);
|
||||
|
||||
const finalStartAnimation = () => {
|
||||
this.stopJSAnimation = startAnimation();
|
||||
};
|
||||
|
||||
this.manager.start([onAnimationStart, begin, finalStartAnimation, duration, onAnimationEnd]);
|
||||
}
|
||||
|
||||
runStepAnimation(props) {
|
||||
const { steps, begin, onAnimationStart } = props;
|
||||
const { style: initialStyle, duration: initialTime = 0 } = steps[0];
|
||||
|
||||
const addStyle = (sequence, nextItem, index) => {
|
||||
if (index === 0) {
|
||||
return sequence;
|
||||
}
|
||||
|
||||
const { duration, easing = 'ease', style, properties: nextProperties, onAnimationEnd } = nextItem;
|
||||
|
||||
const preItem = index > 0 ? steps[index - 1] : nextItem;
|
||||
const properties = nextProperties || Object.keys(style);
|
||||
|
||||
if (typeof easing === 'function' || easing === 'spring') {
|
||||
return [
|
||||
...sequence,
|
||||
this.runJSAnimation.bind(this, {
|
||||
from: preItem.style,
|
||||
to: style,
|
||||
duration,
|
||||
easing,
|
||||
}),
|
||||
duration,
|
||||
];
|
||||
}
|
||||
|
||||
const transition = getTransitionVal(properties, duration, easing);
|
||||
const newStyle = {
|
||||
...preItem.style,
|
||||
...style,
|
||||
transition,
|
||||
};
|
||||
|
||||
return [...sequence, newStyle, duration, onAnimationEnd].filter(identity);
|
||||
};
|
||||
|
||||
return this.manager.start([
|
||||
onAnimationStart,
|
||||
...steps.reduce(addStyle, [initialStyle, Math.max(initialTime, begin)]),
|
||||
props.onAnimationEnd,
|
||||
]);
|
||||
}
|
||||
|
||||
runAnimation(props) {
|
||||
if (!this.manager) {
|
||||
this.manager = createAnimateManager();
|
||||
}
|
||||
const {
|
||||
begin,
|
||||
duration,
|
||||
attributeName,
|
||||
to: propsTo,
|
||||
easing,
|
||||
onAnimationStart,
|
||||
onAnimationEnd,
|
||||
steps,
|
||||
children,
|
||||
} = props;
|
||||
|
||||
const manager = this.manager;
|
||||
|
||||
this.unSubscribe = manager.subscribe(this.handleStyleChange);
|
||||
|
||||
if (typeof easing === 'function' || typeof children === 'function' || easing === 'spring') {
|
||||
this.runJSAnimation(props);
|
||||
return;
|
||||
}
|
||||
|
||||
if (steps.length > 1) {
|
||||
this.runStepAnimation(props);
|
||||
return;
|
||||
}
|
||||
|
||||
const to = attributeName ? { [attributeName]: propsTo } : propsTo;
|
||||
const transition = getTransitionVal(Object.keys(to), duration, easing);
|
||||
|
||||
manager.start([onAnimationStart, begin, { ...to, transition }, duration, onAnimationEnd]);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
children,
|
||||
begin,
|
||||
duration,
|
||||
attributeName,
|
||||
easing,
|
||||
isActive,
|
||||
steps,
|
||||
from,
|
||||
to,
|
||||
canBegin,
|
||||
onAnimationEnd,
|
||||
shouldReAnimate,
|
||||
onAnimationReStart,
|
||||
...others
|
||||
} = this.props;
|
||||
const count = Children.count(children);
|
||||
// eslint-disable-next-line react/destructuring-assignment
|
||||
const stateStyle = this.state.style;
|
||||
|
||||
if (typeof children === 'function') {
|
||||
return children(stateStyle);
|
||||
}
|
||||
|
||||
if (!isActive || count === 0 || duration <= 0) {
|
||||
return children;
|
||||
}
|
||||
|
||||
const cloneContainer = container => {
|
||||
const { style = {}, className } = container.props;
|
||||
|
||||
const res = cloneElement(container, {
|
||||
...others,
|
||||
style: {
|
||||
...style,
|
||||
...stateStyle,
|
||||
},
|
||||
className,
|
||||
});
|
||||
return res;
|
||||
};
|
||||
|
||||
if (count === 1) {
|
||||
return cloneContainer(Children.only(children));
|
||||
}
|
||||
|
||||
return <div>{Children.map(children, child => cloneContainer(child))}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
Animate.displayName = 'Animate';
|
||||
|
||||
Animate.defaultProps = {
|
||||
begin: 0,
|
||||
duration: 1000,
|
||||
from: '',
|
||||
to: '',
|
||||
attributeName: '',
|
||||
easing: 'ease',
|
||||
isActive: true,
|
||||
canBegin: true,
|
||||
steps: [],
|
||||
onAnimationEnd: () => {},
|
||||
onAnimationStart: () => {},
|
||||
};
|
||||
|
||||
Animate.propTypes = {
|
||||
from: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
|
||||
to: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
|
||||
attributeName: PropTypes.string,
|
||||
// animation duration
|
||||
duration: PropTypes.number,
|
||||
begin: PropTypes.number,
|
||||
easing: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
|
||||
steps: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
duration: PropTypes.number.isRequired,
|
||||
style: PropTypes.object.isRequired,
|
||||
easing: PropTypes.oneOfType([
|
||||
PropTypes.oneOf(['ease', 'ease-in', 'ease-out', 'ease-in-out', 'linear']),
|
||||
PropTypes.func,
|
||||
]),
|
||||
// transition css properties(dash case), optional
|
||||
properties: PropTypes.arrayOf('string'),
|
||||
onAnimationEnd: PropTypes.func,
|
||||
}),
|
||||
),
|
||||
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
|
||||
isActive: PropTypes.bool,
|
||||
canBegin: PropTypes.bool,
|
||||
onAnimationEnd: PropTypes.func,
|
||||
// decide if it should reanimate with initial from style when props change
|
||||
shouldReAnimate: PropTypes.bool,
|
||||
onAnimationStart: PropTypes.func,
|
||||
onAnimationReStart: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Animate;
|
||||
37
node_modules/react-smooth/src/AnimateGroup.js
generated
vendored
Normal file
37
node_modules/react-smooth/src/AnimateGroup.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
import React, { Children } from 'react';
|
||||
import { TransitionGroup } from 'react-transition-group';
|
||||
import PropTypes from 'prop-types';
|
||||
import AnimateGroupChild from './AnimateGroupChild';
|
||||
|
||||
function AnimateGroup(props) {
|
||||
const { component, children, appear, enter, leave } = props;
|
||||
|
||||
return (
|
||||
<TransitionGroup component={component}>
|
||||
{Children.map(children, (child, index) => (
|
||||
<AnimateGroupChild
|
||||
appearOptions={appear}
|
||||
enterOptions={enter}
|
||||
leaveOptions={leave}
|
||||
key={`child-${index}`} // eslint-disable-line
|
||||
>
|
||||
{child}
|
||||
</AnimateGroupChild>
|
||||
))}
|
||||
</TransitionGroup>
|
||||
);
|
||||
}
|
||||
|
||||
AnimateGroup.propTypes = {
|
||||
appear: PropTypes.object,
|
||||
enter: PropTypes.object,
|
||||
leave: PropTypes.object,
|
||||
children: PropTypes.oneOfType([PropTypes.array, PropTypes.element]),
|
||||
component: PropTypes.any,
|
||||
};
|
||||
|
||||
AnimateGroup.defaultProps = {
|
||||
component: 'span',
|
||||
};
|
||||
|
||||
export default AnimateGroup;
|
||||
86
node_modules/react-smooth/src/AnimateGroupChild.js
generated
vendored
Normal file
86
node_modules/react-smooth/src/AnimateGroupChild.js
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
import React, { Component, Children } from 'react';
|
||||
import { Transition } from 'react-transition-group';
|
||||
import PropTypes from 'prop-types';
|
||||
import Animate from './Animate';
|
||||
|
||||
const parseDurationOfSingleTransition = (options = {}) => {
|
||||
const { steps, duration } = options;
|
||||
|
||||
if (steps && steps.length) {
|
||||
return steps.reduce(
|
||||
(result, entry) => result + (Number.isFinite(entry.duration) && entry.duration > 0 ? entry.duration : 0),
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
if (Number.isFinite(duration)) {
|
||||
return duration;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
class AnimateGroupChild extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
isActive: false,
|
||||
};
|
||||
}
|
||||
|
||||
handleStyleActive(style) {
|
||||
if (style) {
|
||||
const onAnimationEnd = style.onAnimationEnd
|
||||
? () => {
|
||||
style.onAnimationEnd();
|
||||
}
|
||||
: null;
|
||||
|
||||
this.setState({
|
||||
...style,
|
||||
onAnimationEnd,
|
||||
isActive: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleEnter = (node, isAppearing) => {
|
||||
const { appearOptions, enterOptions } = this.props;
|
||||
|
||||
this.handleStyleActive(isAppearing ? appearOptions : enterOptions);
|
||||
};
|
||||
|
||||
handleExit = () => {
|
||||
const { leaveOptions } = this.props;
|
||||
this.handleStyleActive(leaveOptions);
|
||||
};
|
||||
|
||||
parseTimeout() {
|
||||
const { appearOptions, enterOptions, leaveOptions } = this.props;
|
||||
|
||||
return (
|
||||
parseDurationOfSingleTransition(appearOptions) +
|
||||
parseDurationOfSingleTransition(enterOptions) +
|
||||
parseDurationOfSingleTransition(leaveOptions)
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children, appearOptions, enterOptions, leaveOptions, ...props } = this.props;
|
||||
|
||||
return (
|
||||
<Transition {...props} onEnter={this.handleEnter} onExit={this.handleExit} timeout={this.parseTimeout()}>
|
||||
{() => <Animate {...this.state}>{Children.only(children)}</Animate>}
|
||||
</Transition>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AnimateGroupChild.propTypes = {
|
||||
appearOptions: PropTypes.object,
|
||||
enterOptions: PropTypes.object,
|
||||
leaveOptions: PropTypes.object,
|
||||
children: PropTypes.element,
|
||||
};
|
||||
|
||||
export default AnimateGroupChild;
|
||||
58
node_modules/react-smooth/src/AnimateManager.js
generated
vendored
Normal file
58
node_modules/react-smooth/src/AnimateManager.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
import setRafTimeout from './setRafTimeout';
|
||||
|
||||
export default function createAnimateManager() {
|
||||
let currStyle = {};
|
||||
let handleChange = () => null;
|
||||
let shouldStop = false;
|
||||
|
||||
const setStyle = _style => {
|
||||
if (shouldStop) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(_style)) {
|
||||
if (!_style.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const styles = _style;
|
||||
const [curr, ...restStyles] = styles;
|
||||
|
||||
if (typeof curr === 'number') {
|
||||
setRafTimeout(setStyle.bind(null, restStyles), curr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setStyle(curr);
|
||||
setRafTimeout(setStyle.bind(null, restStyles));
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof _style === 'object') {
|
||||
currStyle = _style;
|
||||
handleChange(currStyle);
|
||||
}
|
||||
|
||||
if (typeof _style === 'function') {
|
||||
_style();
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
stop: () => {
|
||||
shouldStop = true;
|
||||
},
|
||||
start: style => {
|
||||
shouldStop = false;
|
||||
setStyle(style);
|
||||
},
|
||||
subscribe: _handleChange => {
|
||||
handleChange = _handleChange;
|
||||
|
||||
return () => {
|
||||
handleChange = () => null;
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
134
node_modules/react-smooth/src/configUpdate.js
generated
vendored
Normal file
134
node_modules/react-smooth/src/configUpdate.js
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
import { getIntersectionKeys, mapObject } from './util';
|
||||
|
||||
const alpha = (begin, end, k) => begin + (end - begin) * k;
|
||||
const needContinue = ({ from, to }) => from !== to;
|
||||
|
||||
/*
|
||||
* @description: cal new from value and velocity in each stepper
|
||||
* @return: { [styleProperty]: { from, to, velocity } }
|
||||
*/
|
||||
const calStepperVals = (easing, preVals, steps) => {
|
||||
const nextStepVals = mapObject((key, val) => {
|
||||
if (needContinue(val)) {
|
||||
const [newX, newV] = easing(val.from, val.to, val.velocity);
|
||||
return {
|
||||
...val,
|
||||
from: newX,
|
||||
velocity: newV,
|
||||
};
|
||||
}
|
||||
|
||||
return val;
|
||||
}, preVals);
|
||||
|
||||
if (steps < 1) {
|
||||
return mapObject((key, val) => {
|
||||
if (needContinue(val)) {
|
||||
return {
|
||||
...val,
|
||||
velocity: alpha(val.velocity, nextStepVals[key].velocity, steps),
|
||||
from: alpha(val.from, nextStepVals[key].from, steps),
|
||||
};
|
||||
}
|
||||
|
||||
return val;
|
||||
}, preVals);
|
||||
}
|
||||
|
||||
return calStepperVals(easing, nextStepVals, steps - 1);
|
||||
};
|
||||
|
||||
// configure update function
|
||||
export default (from, to, easing, duration, render) => {
|
||||
const interKeys = getIntersectionKeys(from, to);
|
||||
const timingStyle = interKeys.reduce(
|
||||
(res, key) => ({
|
||||
...res,
|
||||
[key]: [from[key], to[key]],
|
||||
}),
|
||||
{},
|
||||
);
|
||||
|
||||
let stepperStyle = interKeys.reduce(
|
||||
(res, key) => ({
|
||||
...res,
|
||||
[key]: {
|
||||
from: from[key],
|
||||
velocity: 0,
|
||||
to: to[key],
|
||||
},
|
||||
}),
|
||||
{},
|
||||
);
|
||||
let cafId = -1;
|
||||
let preTime;
|
||||
let beginTime;
|
||||
let update = () => null;
|
||||
|
||||
const getCurrStyle = () => mapObject((key, val) => val.from, stepperStyle);
|
||||
const shouldStopAnimation = () => !Object.values(stepperStyle).filter(needContinue).length;
|
||||
|
||||
// stepper timing function like spring
|
||||
const stepperUpdate = now => {
|
||||
if (!preTime) {
|
||||
preTime = now;
|
||||
}
|
||||
const deltaTime = now - preTime;
|
||||
const steps = deltaTime / easing.dt;
|
||||
|
||||
stepperStyle = calStepperVals(easing, stepperStyle, steps);
|
||||
// get union set and add compatible prefix
|
||||
render({
|
||||
...from,
|
||||
...to,
|
||||
...getCurrStyle(stepperStyle),
|
||||
});
|
||||
|
||||
preTime = now;
|
||||
|
||||
if (!shouldStopAnimation()) {
|
||||
cafId = requestAnimationFrame(update);
|
||||
}
|
||||
};
|
||||
|
||||
// t => val timing function like cubic-bezier
|
||||
const timingUpdate = now => {
|
||||
if (!beginTime) {
|
||||
beginTime = now;
|
||||
}
|
||||
|
||||
const t = (now - beginTime) / duration;
|
||||
const currStyle = mapObject((key, val) => alpha(...val, easing(t)), timingStyle);
|
||||
|
||||
// get union set and add compatible prefix
|
||||
render({
|
||||
...from,
|
||||
...to,
|
||||
...currStyle,
|
||||
});
|
||||
|
||||
if (t < 1) {
|
||||
cafId = requestAnimationFrame(update);
|
||||
} else {
|
||||
const finalStyle = mapObject((key, val) => alpha(...val, easing(1)), timingStyle);
|
||||
|
||||
render({
|
||||
...from,
|
||||
...to,
|
||||
...finalStyle,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
update = easing.isStepper ? stepperUpdate : timingUpdate;
|
||||
|
||||
// return start animation method
|
||||
return () => {
|
||||
requestAnimationFrame(update);
|
||||
|
||||
// return stop animation method
|
||||
return () => {
|
||||
cancelAnimationFrame(cafId);
|
||||
};
|
||||
};
|
||||
};
|
||||
159
node_modules/react-smooth/src/easing.js
generated
vendored
Normal file
159
node_modules/react-smooth/src/easing.js
generated
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
import { warn } from './util';
|
||||
|
||||
const ACCURACY = 1e-4;
|
||||
|
||||
const cubicBezierFactor = (c1, c2) => [0, 3 * c1, 3 * c2 - 6 * c1, 3 * c1 - 3 * c2 + 1];
|
||||
|
||||
const multyTime = (params, t) => params.map((param, i) => param * t ** i).reduce((pre, curr) => pre + curr);
|
||||
|
||||
const cubicBezier = (c1, c2) => t => {
|
||||
const params = cubicBezierFactor(c1, c2);
|
||||
|
||||
return multyTime(params, t);
|
||||
};
|
||||
|
||||
const derivativeCubicBezier = (c1, c2) => t => {
|
||||
const params = cubicBezierFactor(c1, c2);
|
||||
const newParams = [...params.map((param, i) => param * i).slice(1), 0];
|
||||
|
||||
return multyTime(newParams, t);
|
||||
};
|
||||
|
||||
// calculate cubic-bezier using Newton's method
|
||||
export const configBezier = (...args) => {
|
||||
let [x1, y1, x2, y2] = args;
|
||||
|
||||
if (args.length === 1) {
|
||||
switch (args[0]) {
|
||||
case 'linear':
|
||||
[x1, y1, x2, y2] = [0.0, 0.0, 1.0, 1.0];
|
||||
break;
|
||||
case 'ease':
|
||||
[x1, y1, x2, y2] = [0.25, 0.1, 0.25, 1.0];
|
||||
break;
|
||||
case 'ease-in':
|
||||
[x1, y1, x2, y2] = [0.42, 0.0, 1.0, 1.0];
|
||||
break;
|
||||
case 'ease-out':
|
||||
[x1, y1, x2, y2] = [0.42, 0.0, 0.58, 1.0];
|
||||
break;
|
||||
case 'ease-in-out':
|
||||
[x1, y1, x2, y2] = [0.0, 0.0, 0.58, 1.0];
|
||||
break;
|
||||
default: {
|
||||
const easing = args[0].split('(');
|
||||
if (easing[0] === 'cubic-bezier' && easing[1].split(')')[0].split(',').length === 4) {
|
||||
[x1, y1, x2, y2] = easing[1]
|
||||
.split(')')[0]
|
||||
.split(',')
|
||||
.map(x => parseFloat(x));
|
||||
} else {
|
||||
warn(
|
||||
false,
|
||||
'[configBezier]: arguments should be one of ' +
|
||||
"oneOf 'linear', 'ease', 'ease-in', 'ease-out', " +
|
||||
"'ease-in-out','cubic-bezier(x1,y1,x2,y2)', instead received %s",
|
||||
args,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
warn(
|
||||
[x1, x2, y1, y2].every(num => typeof num === 'number' && num >= 0 && num <= 1),
|
||||
'[configBezier]: arguments should be x1, y1, x2, y2 of [0, 1] instead received %s',
|
||||
args,
|
||||
);
|
||||
|
||||
const curveX = cubicBezier(x1, x2);
|
||||
const curveY = cubicBezier(y1, y2);
|
||||
const derCurveX = derivativeCubicBezier(x1, x2);
|
||||
const rangeValue = value => {
|
||||
if (value > 1) {
|
||||
return 1;
|
||||
}
|
||||
if (value < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
const bezier = _t => {
|
||||
const t = _t > 1 ? 1 : _t;
|
||||
let x = t;
|
||||
|
||||
for (let i = 0; i < 8; ++i) {
|
||||
const evalT = curveX(x) - t;
|
||||
const derVal = derCurveX(x);
|
||||
|
||||
if (Math.abs(evalT - t) < ACCURACY || derVal < ACCURACY) {
|
||||
return curveY(x);
|
||||
}
|
||||
|
||||
x = rangeValue(x - evalT / derVal);
|
||||
}
|
||||
|
||||
return curveY(x);
|
||||
};
|
||||
|
||||
bezier.isStepper = false;
|
||||
|
||||
return bezier;
|
||||
};
|
||||
|
||||
export const configSpring = (config = {}) => {
|
||||
const { stiff = 100, damping = 8, dt = 17 } = config;
|
||||
const stepper = (currX, destX, currV) => {
|
||||
const FSpring = -(currX - destX) * stiff;
|
||||
const FDamping = currV * damping;
|
||||
const newV = currV + ((FSpring - FDamping) * dt) / 1000;
|
||||
const newX = (currV * dt) / 1000 + currX;
|
||||
|
||||
if (Math.abs(newX - destX) < ACCURACY && Math.abs(newV) < ACCURACY) {
|
||||
return [destX, 0];
|
||||
}
|
||||
return [newX, newV];
|
||||
};
|
||||
|
||||
stepper.isStepper = true;
|
||||
stepper.dt = dt;
|
||||
|
||||
return stepper;
|
||||
};
|
||||
|
||||
export const configEasing = (...args) => {
|
||||
const [easing] = args;
|
||||
|
||||
if (typeof easing === 'string') {
|
||||
switch (easing) {
|
||||
case 'ease':
|
||||
case 'ease-in-out':
|
||||
case 'ease-out':
|
||||
case 'ease-in':
|
||||
case 'linear':
|
||||
return configBezier(easing);
|
||||
case 'spring':
|
||||
return configSpring();
|
||||
default:
|
||||
if (easing.split('(')[0] === 'cubic-bezier') {
|
||||
return configBezier(easing);
|
||||
}
|
||||
warn(
|
||||
false,
|
||||
"[configEasing]: first argument should be one of 'ease', 'ease-in', " +
|
||||
"'ease-out', 'ease-in-out','cubic-bezier(x1,y1,x2,y2)', 'linear' and 'spring', instead received %s",
|
||||
args,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof easing === 'function') {
|
||||
return easing;
|
||||
}
|
||||
|
||||
warn(false, '[configEasing]: first argument type should be function or string, instead received %s', args);
|
||||
|
||||
return null;
|
||||
};
|
||||
7
node_modules/react-smooth/src/index.js
generated
vendored
Normal file
7
node_modules/react-smooth/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import Animate from './Animate';
|
||||
import { configBezier, configSpring } from './easing';
|
||||
import AnimateGroup from './AnimateGroup';
|
||||
|
||||
export { configSpring, configBezier, AnimateGroup };
|
||||
|
||||
export default Animate;
|
||||
22
node_modules/react-smooth/src/setRafTimeout.js
generated
vendored
Normal file
22
node_modules/react-smooth/src/setRafTimeout.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
function safeRequestAnimationFrame(callback) {
|
||||
if (typeof requestAnimationFrame !== 'undefined') requestAnimationFrame(callback);
|
||||
}
|
||||
|
||||
export default function setRafTimeout(callback, timeout = 0) {
|
||||
let currTime = -1;
|
||||
|
||||
const shouldUpdate = now => {
|
||||
if (currTime < 0) {
|
||||
currTime = now;
|
||||
}
|
||||
|
||||
if (now - currTime > timeout) {
|
||||
callback(now);
|
||||
currTime = -1;
|
||||
} else {
|
||||
safeRequestAnimationFrame(shouldUpdate);
|
||||
}
|
||||
};
|
||||
|
||||
requestAnimationFrame(shouldUpdate);
|
||||
}
|
||||
82
node_modules/react-smooth/src/util.js
generated
vendored
Normal file
82
node_modules/react-smooth/src/util.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/* eslint no-console: 0 */
|
||||
|
||||
export const getIntersectionKeys = (preObj, nextObj) =>
|
||||
[Object.keys(preObj), Object.keys(nextObj)].reduce((a, b) => a.filter(c => b.includes(c)));
|
||||
|
||||
export const identity = param => param;
|
||||
|
||||
/*
|
||||
* @description: convert camel case to dash case
|
||||
* string => string
|
||||
*/
|
||||
export const getDashCase = name => name.replace(/([A-Z])/g, v => `-${v.toLowerCase()}`);
|
||||
|
||||
export const log = (...args) => {
|
||||
console.log(...args);
|
||||
};
|
||||
|
||||
/*
|
||||
* @description: log the value of a varible
|
||||
* string => any => any
|
||||
*/
|
||||
export const debug = name => item => {
|
||||
log(name, item);
|
||||
|
||||
return item;
|
||||
};
|
||||
|
||||
/*
|
||||
* @description: log name, args, return value of a function
|
||||
* function => function
|
||||
*/
|
||||
export const debugf =
|
||||
(tag, f) =>
|
||||
(...args) => {
|
||||
const res = f(...args);
|
||||
const name = tag || f.name || 'anonymous function';
|
||||
const argNames = `(${args.map(JSON.stringify).join(', ')})`;
|
||||
|
||||
log(`${name}: ${argNames} => ${JSON.stringify(res)}`);
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
/*
|
||||
* @description: map object on every element in this object.
|
||||
* (function, object) => object
|
||||
*/
|
||||
export const mapObject = (fn, obj) =>
|
||||
Object.keys(obj).reduce(
|
||||
(res, key) => ({
|
||||
...res,
|
||||
[key]: fn(key, obj[key]),
|
||||
}),
|
||||
{},
|
||||
);
|
||||
|
||||
export const getTransitionVal = (props, duration, easing) =>
|
||||
props.map(prop => `${getDashCase(prop)} ${duration}ms ${easing}`).join(',');
|
||||
|
||||
const isDev = process.env.NODE_ENV !== 'production';
|
||||
|
||||
export const warn = (condition, format, a, b, c, d, e, f) => {
|
||||
if (isDev && typeof console !== 'undefined' && console.warn) {
|
||||
if (format === undefined) {
|
||||
console.warn('LogUtils requires an error message argument');
|
||||
}
|
||||
|
||||
if (!condition) {
|
||||
if (format === undefined) {
|
||||
console.warn(
|
||||
'Minified exception occurred; use the non-minified dev environment ' +
|
||||
'for the full error message and additional helpful warnings.',
|
||||
);
|
||||
} else {
|
||||
const args = [a, b, c, d, e, f];
|
||||
let argIndex = 0;
|
||||
|
||||
console.warn(format.replace(/%s/g, () => args[argIndex++]));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user