This is an old code I have to do spring animations in our app:
/**
Spring are configurable and can be tuned.
mass - Spring mass
tension - Spring energetic load
friction - Spring resistence
duration - If > than 0 will switch to a duration-based animation instead of spring physics, value should be indicated in milliseconds
*/
module Config = {
[@bs.deriving abstract]
type t = {
[@bs.optional]
mass: int,
[@bs.optional]
tension: int,
[@bs.optional]
friction: int,
[@bs.optional]
duration: int,
};
};
/**
Spring props can be anything, not just styles
*/
module Props = {
type t('a) = Js.t('a);
external fromStyle: ReactDOMRe.Style.t => t('a) = "%identity";
};
/**
The spring itself
*/
[@bs.deriving abstract]
type t('source, 'target) = {
[@bs.optional]
config: Config.t,
[@bs.optional]
from: Props.t('source),
[@bs.optional] [@bs.as "to"]
toValue: Props.t('target),
};
module Preset = {
[@bs.module "react-spring/web.cjs"] [@bs.scope "config"] external default: Config.t = "default";
[@bs.module "react-spring/web.cjs"] [@bs.scope "config"] external gentle: Config.t = "gentle";
[@bs.module "react-spring/web.cjs"] [@bs.scope "config"] external wobbly: Config.t = "wobbly";
[@bs.module "react-spring/web.cjs"] [@bs.scope "config"] external stiff: Config.t = "stiff";
[@bs.module "react-spring/web.cjs"] [@bs.scope "config"] external slow: Config.t = "slow";
[@bs.module "react-spring/web.cjs"] [@bs.scope "config"] external molasses: Config.t = "molasses";
let fast = Config.t(~mass=1, ~tension=500, ~friction=30, ());
};
/**
Turns values into animated-values.
*/
[@bs.module "react-spring/web.cjs"]
external useSpring: (unit => t('from, 'toValue)) => ('props, (. t('from, 'toValue)) => unit, 'stop) = "useSpring";
module Transition = {
module ObjConfig = {
[@bs.deriving abstract]
type t('from, 'enter, 'leave) = {
[@bs.optional]
config: Config.t,
[@bs.optional]
from: Props.t('from),
[@bs.optional]
enter: Props.t('enter),
[@bs.optional]
leave: Props.t('leave),
};
};
module FnConfig = {
[@bs.deriving abstract]
type t('item, 'from, 'enter, 'leave, 'a) = {
[@bs.optional]
config: Config.t,
[@bs.optional]
from: Props.t('from),
[@bs.optional]
enter: 'item => (. ((. Props.t('enter)) => 'a)) => Js.Promise.t('a),
[@bs.optional]
leave: Props.t('leave),
};
};
module ItemConfig = {
[@bs.deriving abstract]
type t('item, 'from, 'enter, 'update, 'leave, 'a) = {
[@bs.optional]
config: Config.t,
[@bs.optional]
from: 'item => Props.t('from),
[@bs.optional]
enter: 'item => Props.t('enter),
[@bs.optional]
update: 'item => Props.t('update),
[@bs.optional]
leave: Props.t('leave),
};
};
[@bs.deriving abstract]
type t('item, 'a) = {
item: 'item,
key: string,
props: 'a,
};
};
[@bs.module "react-spring/web.cjs"]
external useTransitionObj:
(array('item), option('item => string), Transition.ObjConfig.t('from, 'enter, 'leave)) =>
array(Transition.t('item, 'a)) =
"useTransition";
[@bs.module "react-spring/web.cjs"]
external useTransitionFn:
(array('item), option('item => string), Transition.FnConfig.t('item, 'from, 'enter, 'leave, 'a)) =>
array(Transition.t('item, 'a)) =
"useTransition";
[@bs.module "react-spring/web.cjs"]
external useTransitionItem:
(array('item), option('item => string), Transition.ItemConfig.t('item, 'from, 'enter, 'update, 'leave, 'a)) =>
array(Transition.t('item, 'a)) =
"useTransition";
module Animated = {
/**
Component extension to an animated one
*/
[@bs.module "react-spring/web.cjs"] [@react.component] [@bs.scope "animated"]
external make:
(~ref: ReactDOMRe.Ref.t=?, ~style: Js.t('a)=?, ~className: string=?, ~children: React.element=?) => 'children =
"div";
};
I copy paste it as is: the code is old and certainly not a state of the art, but it was enough for us.
It might help you to get started.
I use it with some code like this:
let config = Config.t(~duration=..., ());
let (props, setProps, stopProps) = useSpring(() => t(~config=config, ~from=..., ~toValue=..., ()))
<Spring.Animated style=props>