Skip to content

Commit

Permalink
feat: add <Tween> component
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Feb 23, 2018
1 parent ea1f812 commit 677d3e7
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 0 deletions.
59 changes: 59 additions & 0 deletions src/Tween/easing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
export type TEasing = (time: number) => number;

export interface IEasingMap {
linear: TEasing;
inQuad: TEasing;
outQuad: TEasing;
inOutQuad: TEasing;
inCubic: TEasing;
outCubic: TEasing;
inOutCubic: TEasing;
inQuart: TEasing;
outQuart: TEasing;
inOutQuart: TEasing;
inQuint: TEasing;
outQuint: TEasing;
inOutQuint: TEasing;
}

// From: https://gist.github.com/gre/1650294
export const easing: IEasingMap = {
// no easing, no acceleration
linear: (t) => t,

// accelerating from zero velocity
inQuad: (t) => t*t,

// decelerating to zero velocity
outQuad: (t) => t*(2-t),

// acceleration until halfway, then deceleration
inOutQuad: (t) => t<.5 ? 2*t*t : -1+(4-2*t)*t,

// accelerating from zero velocity
inCubic: (t) => t*t*t,

// decelerating to zero velocity
outCubic: (t) => (--t)*t*t+1,

// acceleration until halfway, then deceleration
inOutCubic: (t) => t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1,

// accelerating from zero velocity
inQuart: (t) => t*t*t*t,

// decelerating to zero velocity
outQuart: (t) => 1-(--t)*t*t*t,

// acceleration until halfway, then deceleration
inOutQuart: (t) => t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t,

// accelerating from zero velocity
inQuint: (t) => t*t*t*t*t,

// decelerating to zero velocity
outQuint: (t) => 1+(--t)*t*t*t*t,

// acceleration until halfway, then deceleration
inOutQuint: (t) => t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t
};
45 changes: 45 additions & 0 deletions src/Tween/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {render, createEnhancer} from 'react-universal-interface';
import {Render, IRenderProps} from '../Render';
import {h} from '../util';
import {easing, TEasing, IEasingMap} from './easing';

export interface ITweenProps extends IRenderProps {
easing: (keyof IEasingMap) | [number, number, number, number] | ((time: number) => number);
Render: React.SFC<IRenderProps> | React.ComponentClass<IRenderProps>;
}

export const Tween: React.SFC<ITweenProps> = (props) => {
let {easing: fn} = props;

switch (typeof props.easing) {
case 'string':
fn = easing[fn as string];
break;
case 'object':
// TODO: Implement cubic-bezier
}

if (process.env.NODE_ENV !== 'production') {
if (typeof fn !== 'function') {
console.error(
'<Tween> expected "easing" property to be a valid easing function or a 4-tuple array or numbers ' +
'specifying a Cubic Bezier curve, or a string specifying one of the built-int easing functions: ' +
'"' + Object.keys(easing).join('", "') + '".'
);
console.trace();

return null;
}
}

return h(props.Render, props,
({value}) => render(props, {value: (fn as TEasing)(value)})
);
};

Tween.defaultProps = {
easing: 'linear',
Render
};

export const withTween = createEnhancer(Tween, 'tween');

0 comments on commit 677d3e7

Please sign in to comment.