Skip to content

Instantly share code, notes, and snippets.

@jfrolich
Created December 22, 2020 08:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfrolich/0ac86f998e5fa51a87d18e2c0f59958d to your computer and use it in GitHub Desktop.
Save jfrolich/0ac86f998e5fa51a87d18e2c0f59958d to your computer and use it in GitHub Desktop.
Reanimated2 Bindings
module Extrapolate = {
type t
@bs.scope(("default", "Extrapolate")) @bs.module("react-native-reanimated")
external extend: t = "EXTEND"
@bs.scope(("default", "Extrapolate")) @bs.module("react-native-reanimated")
external clamp: t = "CLAMP"
@bs.scope(("default", "Extrapolate")) @bs.module("react-native-reanimated")
external identity: t = "IDENTITY"
}
module Value = {
type t
module Interpolation = {
type config = {
inputRange: array<float>,
outputRange: array<float>,
}
type dynamicConfig = {
inputRange: array<t>,
outputRange: array<t>,
}
type dynamicConfigFull = {
inputRange: array<t>,
outputRange: array<t>,
extrapolateLeft: Extrapolate.t,
extrapolateRight: Extrapolate.t,
}
type configFull = {
inputRange: array<float>,
outputRange: array<float>,
extrapolateLeft: Extrapolate.t,
extrapolateRight: Extrapolate.t,
}
}
@bs.scope("default") @bs.module("react-native-reanimated") @bs.new
external make: float => t = "Value"
external makeFromValue: t => t = "Value"
external toAnimated: float => t = "%identity"
external intToAnimated: int => t = "%identity"
external boolToAnimated: bool => t = "%identity"
@bs.send external set: (t, t) => unit = "setValue"
@bs.scope("default") @bs.module("react-native-reanimated")
external interpolate: (t, Interpolation.config) => t = "interpolateNode"
@bs.scope("default") @bs.module("react-native-reanimated")
external interpolateDynamic: (t, Interpolation.dynamicConfig) => t = "interpolateNode"
@bs.scope("default") @bs.module("react-native-reanimated")
external interpolateFull: (t, Interpolation.configFull) => t = "interpolateNode"
@bs.scope("default") @bs.module("react-native-reanimated")
external interpolateDynamicFull: (t, Interpolation.dynamicConfigFull) => t = "interpolateNode"
let setInitial = (value: t, initialValue: float): t => {
Obj.magic(value)["__Custom_InitialValue"] = initialValue
value
}
}
module Clock = {
type t
@bs.scope("default") @bs.module("react-native-reanimated") @bs.new
external make: unit => t = "Clock"
external toValue: t => Value.t = "%identity"
}
type springConfig = {
mass: float,
stiffness: float,
damping: float,
overshootClamping: bool,
restSpeedThreshold: float,
restDisplacementThreshold: float,
toValue: Value.t,
}
type springState = {
finished: Value.t,
velocity: Value.t,
position: Value.t,
time: Value.t,
}
module SpringUtils = {
@bs.scope(("default", "SpringUtils")) @bs.module("react-native-reanimated")
external makeDefaultConfig: unit => springConfig = "makeDefaultConfig"
}
module InterpolatedValue = {
type t
external toFloat: t => float = "%identity"
}
// copied and modified from reason-react-native
module Event = {
type contentOffset = {y: option<Value.t>}
type nativeEventMapping = {
translationX: option<Value.t>,
velocityX: option<Value.t>,
state: option<Value.t>,
contentOffset: option<contentOffset>,
x: option<Value.t>,
}
type mapping = {nativeEvent: nativeEventMapping}
let defaultContentOffset = {y: None}
let defaultEvent = {
translationX: None,
velocityX: None,
state: None,
contentOffset: None,
x: None,
}
}
@bs.scope("default") @bs.module("react-native-reanimated")
external spring: (Clock.t, springState, springConfig) => Value.t = "spring"
@bs.scope("default") @bs.module("react-native-reanimated")
external block: array<Value.t> => Value.t = "block"
@bs.scope("default") @bs.module("react-native-reanimated")
external cond: (Value.t, Value.t, Value.t) => Value.t = "cond"
@bs.scope("default") @bs.module("react-native-reanimated")
external add: (Value.t, Value.t) => Value.t = "add"
@bs.scope("default") @bs.module("react-native-reanimated")
external not__: Value.t => Value.t = "not"
@bs.scope("default") @bs.module("react-native-reanimated")
external absolute: Value.t => Value.t = "abs"
@bs.scope("default") @bs.module("react-native-reanimated")
external greaterThan: (Value.t, Value.t) => Value.t = "greaterThan"
@bs.scope("default") @bs.module("react-native-reanimated")
external greaterOrEq: (Value.t, Value.t) => Value.t = "greaterOrEq"
@bs.scope("default") @bs.module("react-native-reanimated")
external lessThan: (Value.t, Value.t) => Value.t = "lessThan"
@bs.scope("default") @bs.module("react-native-reanimated")
external lessOrEq: (Value.t, Value.t) => Value.t = "lessOrEq"
@bs.scope("default") @bs.module("react-native-reanimated")
external sub: (Value.t, Value.t) => Value.t = "sub"
@bs.scope("default") @bs.module("react-native-reanimated")
external eq: (Value.t, Value.t) => Value.t = "eq"
@bs.scope("default") @bs.module("react-native-reanimated")
external neq: (Value.t, Value.t) => Value.t = "neq"
@bs.scope("default") @bs.module("react-native-reanimated")
external color: (Value.t, Value.t, Value.t, Value.t) => Value.t = "color"
@bs.scope("default") @bs.module("react-native-reanimated")
external maximum: (Value.t, Value.t) => Value.t = "max"
@bs.scope("default") @bs.module("react-native-reanimated")
external minimum: (Value.t, Value.t) => Value.t = "min"
@bs.scope("default") @bs.module("react-native-reanimated")
external round: Value.t => Value.t = "round"
@bs.scope("default") @bs.module("react-native-reanimated")
external divide: (Value.t, Value.t) => Value.t = "divide"
@bs.scope("default") @bs.module("react-native-reanimated")
external multiply: (Value.t, Value.t) => Value.t = "multiply"
@bs.scope("default") @bs.module("react-native-reanimated")
external onChange: (Value.t, Value.t) => Value.t = "onChange"
@bs.scope("default") @bs.module("react-native-reanimated")
external cond1: (Value.t, Value.t) => Value.t = "cond"
@bs.scope("default") @bs.module("react-native-reanimated")
external startClock: Clock.t => Value.t = "startClock"
@bs.scope("default") @bs.module("react-native-reanimated")
external stopClock: Clock.t => Value.t = "stopClock"
@bs.scope("default") @bs.module("react-native-reanimated")
external clockRunning: Clock.t => Value.t = "clockRunning"
@bs.scope("default") @bs.module("react-native-reanimated")
external set: (Value.t, Value.t) => Value.t = "set"
@bs.scope("default") @bs.module("react-native-reanimated")
external modulo: (Value.t, Value.t) => Value.t = "modulo"
type callFn = array<InterpolatedValue.t> => unit
@bs.scope("default") @bs.module("react-native-reanimated")
external call: (array<Value.t>, callFn) => Value.t = "call"
@bs.scope("default") @bs.module("react-native-reanimated")
external or_: (Value.t, Value.t) => Value.t = "or"
@bs.scope("default") @bs.module("react-native-reanimated")
external debug: (string, Value.t) => Value.t = "debug"
@bs.scope("default") @bs.module("react-native-reanimated")
external and_: (Value.t, Value.t) => Value.t = "and"
@bs.scope("default") @bs.module("react-native-reanimated")
external and3: (Value.t, Value.t, Value.t) => Value.t = "and"
@bs.scope("default") @bs.module("react-native-reanimated")
external and4: (Value.t, Value.t, Value.t, Value.t) => Value.t = "and"
@bs.scope("default") @bs.module("react-native-reanimated")
external and5: (Value.t, Value.t, Value.t, Value.t, Value.t) => Value.t = "and"
@bs.scope("default") @bs.module("react-native-reanimated")
external concat: (Value.t, string) => Value.t = "concat"
type arg = unit => Value.t
@bs.scope("default") @bs.module("react-native-reanimated")
external useCode1: (arg, array<'a>) => unit = "useCode"
@bs.scope("default") @bs.module("react-native-reanimated")
external createAnimatedComponent: 'a => 'a = "createAnimatedComponent"
type pressEventRet = ReactNative.Event.pressEvent => unit
@bs.scope("default") @bs.module("react-native-reanimated")
external pressEvent: array<Event.mapping> => pressEventRet = "event"
type scrollEventRet = ReactNative.Event.scrollEvent => unit
@bs.scope("default") @bs.module("react-native-reanimated")
external scrollEvent: array<Event.mapping> => scrollEventRet = "event"
type gestureEventRet = RNGestureHandler.Event.gestureEvent => unit
@bs.scope("default") @bs.module("react-native-reanimated")
external gestureEvent: array<Event.mapping> => gestureEventRet = "event"
module StyleProp = {
// methods to allow use of Animated values with Style props
// these methods should not be used to get the current value
// for angle, Color.t, and size expressed as percentage,
// interpolated values are needed where the outputRange is
// an appropriate array of strings
external float: Value.t => float = "%identity"
external int: Value.t => int = "%identity"
external unsafeAngle: Value.t => ReactNative.Style.angle = "%identity"
let angle: Value.t => ReactNative.Style.angle = angle => concat(angle, "deg")->unsafeAngle
external size: Value.t => ReactNative.Style.size = "%identity"
external margin: Value.t => ReactNative.Style.margin = "%identity"
external color: Value.t => ReactNative.Color.t = "%identity"
}
let interpolateColorNode = (t, (r, g, b, a), (r', g', b', a')) => {
let a = Belt.Option.getWithDefault(a, 1.)
let a' = Belt.Option.getWithDefault(a', 1.)
color(
round(
Value.interpolateFull(
t,
{
inputRange: [0., 1.],
outputRange: [r', r],
extrapolateLeft: Extrapolate.clamp,
extrapolateRight: Extrapolate.clamp,
},
),
),
round(
Value.interpolateFull(
t,
{
inputRange: [0., 1.],
outputRange: [g', g],
extrapolateLeft: Extrapolate.clamp,
extrapolateRight: Extrapolate.clamp,
},
),
),
round(
Value.interpolateFull(
t,
{
inputRange: [0., 1.],
outputRange: [b', b],
extrapolateLeft: Extrapolate.clamp,
extrapolateRight: Extrapolate.clamp,
},
),
),
Value.interpolateFull(
t,
{
inputRange: [0., 1.],
outputRange: [a', a],
extrapolateLeft: Extrapolate.clamp,
extrapolateRight: Extrapolate.clamp,
},
),
)->StyleProp.color
}
///////////////////////////////////////////////////////////////////////////////
/////////////////////// V2
///////////////////////////////////////////////////////////////////////////////
// this is version two. Everything above still works with version 2, but the
// below is the new API. Will build this while building features.
// once the API surface looks good, we can finalize and contribute the whole
// to open-source
module AnimationObject = {
// phantom type. An animation object can wrap a specific type, we need to
// parameterize it to make sure the types are sound.
type t<'a>
// everything that accepts an animation object also accepts the original value
// so to have a single type we can just cast to identity
external make: 'a => t<'a> = "%identity"
}
module SharedValue = {
type t<'a> = {mutable value: 'a}
}
module AnimatedStyle = {
type t
type transform
type offset
@bs.obj
external offset: (~height: AnimationObject.t<float>, ~width: AnimationObject.t<float>) => offset =
""
@bs.obj
external perspective: (~perspective: AnimationObject.t<float>) => transform = ""
@bs.obj
external rotate: (~rotate: AnimationObject.t<ReactNative.Style.angle>) => transform = ""
@bs.obj
external rotateX: (~rotateX: AnimationObject.t<ReactNative.Style.angle>) => transform = ""
@bs.obj
external rotateZ: (~rotateZ: AnimationObject.t<ReactNative.Style.angle>) => transform = ""
@bs.obj external scale: (~scale: AnimationObject.t<float>) => transform = ""
@bs.obj external scaleX: (~scaleX: AnimationObject.t<float>) => transform = ""
@bs.obj external scaleY: (~scaleY: AnimationObject.t<float>) => transform = ""
@bs.obj
external translateX: (~translateX: AnimationObject.t<float>) => transform = ""
@bs.obj
external translateY: (~translateY: AnimationObject.t<float>) => transform = ""
@bs.obj
external skewX: (~skewX: AnimationObject.t<ReactNative.Style.angle>) => transform = ""
@bs.obj
external skewY: (~skewY: AnimationObject.t<ReactNative.Style.angle>) => transform = ""
// normal styles are also valid animated styles
external make: ReactNative.Style.t => t = "%identity"
// tried to iomplement most styles that are "animatable"
// can be expanded to have more.
@bs.obj
external style: (
~overlayColor: AnimationObject.t<ReactNative.Color.t>=?,
~tintColor: AnimationObject.t<ReactNative.Color.t>=?,
~color: AnimationObject.t<ReactNative.Color.t>=?,
~fontSize: AnimationObject.t<float>=?,
~letterSpacing: AnimationObject.t<float>=?,
~lineHeight: AnimationObject.t<float>=?,
~textDecorationColor: AnimationObject.t<ReactNative.Color.t>=?,
~textShadowColor: AnimationObject.t<ReactNative.Color.t>=?,
~textShadowRadius: AnimationObject.t<float>=?,
~textShadowOffset: offset=?,
~backgroundColor: AnimationObject.t<ReactNative.Color.t>=?,
~borderBottomColor: AnimationObject.t<ReactNative.Color.t>=?,
~borderBottomEndRadius: AnimationObject.t<float>=?,
~borderBottomLeftRadius: AnimationObject.t<float>=?,
~borderBottomRightRadius: AnimationObject.t<float>=?,
~borderBottomStartRadius: AnimationObject.t<float>=?,
~borderBottomWidth: AnimationObject.t<float>=?,
~borderColor: AnimationObject.t<ReactNative.Color.t>=?,
~borderEndColor: AnimationObject.t<ReactNative.Color.t>=?,
~borderEndWidth: AnimationObject.t<float>=?,
~borderLeftColor: AnimationObject.t<ReactNative.Color.t>=?,
~borderLeftWidth: AnimationObject.t<float>=?,
~borderRadius: AnimationObject.t<float>=?,
~borderRightColor: AnimationObject.t<ReactNative.Color.t>=?,
~borderRightWidth: AnimationObject.t<float>=?,
~borderStartColor: AnimationObject.t<ReactNative.Color.t>=?,
~borderStartWidth: AnimationObject.t<float>=?,
~borderTopColor: AnimationObject.t<ReactNative.Color.t>=?,
~borderTopEndRadius: AnimationObject.t<float>=?,
~borderTopLeftRadius: AnimationObject.t<float>=?,
~borderTopRightRadius: AnimationObject.t<float>=?,
~borderTopStartRadius: AnimationObject.t<float>=?,
~borderTopWidth: AnimationObject.t<float>=?,
~borderWidth: AnimationObject.t<float>=?,
~elevation: AnimationObject.t<float>=?,
~opacity: AnimationObject.t<float>=?,
~transform: array<transform>=?,
~shadowColor: AnimationObject.t<ReactNative.Color.t>=?,
~shadowOffset: offset=?,
~shadowOpacity: AnimationObject.t<float>=?,
~shadowRadius: AnimationObject.t<float>=?,
~aspectRatio: AnimationObject.t<float>=?,
~bottom: AnimationObject.t<ReactNative.Style.size>=?,
~_end: AnimationObject.t<ReactNative.Style.size>=?,
~flex: AnimationObject.t<float>=?,
~flexBasis: AnimationObject.t<ReactNative.Style.margin>=?,
~flexGrow: AnimationObject.t<float>=?,
~flexShrink: AnimationObject.t<float>=?,
~height: AnimationObject.t<ReactNative.Style.size>=?,
~left: AnimationObject.t<ReactNative.Style.size>=?,
~margin: AnimationObject.t<ReactNative.Style.margin>=?,
~marginBottom: AnimationObject.t<ReactNative.Style.margin>=?,
~marginEnd: AnimationObject.t<ReactNative.Style.margin>=?,
~marginHorizontal: AnimationObject.t<ReactNative.Style.margin>=?,
~marginLeft: AnimationObject.t<ReactNative.Style.margin>=?,
~marginRight: AnimationObject.t<ReactNative.Style.margin>=?,
~marginStart: AnimationObject.t<ReactNative.Style.margin>=?,
~marginTop: AnimationObject.t<ReactNative.Style.margin>=?,
~marginVertical: AnimationObject.t<ReactNative.Style.margin>=?,
~maxHeight: AnimationObject.t<ReactNative.Style.size>=?,
~maxWidth: AnimationObject.t<ReactNative.Style.size>=?,
~minHeight: AnimationObject.t<ReactNative.Style.size>=?,
~minWidth: AnimationObject.t<ReactNative.Style.size>=?,
~padding: AnimationObject.t<ReactNative.Style.size>=?,
~paddingBottom: AnimationObject.t<ReactNative.Style.size>=?,
~paddingEnd: AnimationObject.t<ReactNative.Style.size>=?,
~paddingHorizontal: AnimationObject.t<ReactNative.Style.size>=?,
~paddingLeft: AnimationObject.t<ReactNative.Style.size>=?,
~paddingRight: AnimationObject.t<ReactNative.Style.size>=?,
~paddingStart: AnimationObject.t<ReactNative.Style.size>=?,
~paddingTop: AnimationObject.t<ReactNative.Style.size>=?,
~paddingVertical: AnimationObject.t<ReactNative.Style.size>=?,
~right: AnimationObject.t<ReactNative.Style.size>=?,
~start: AnimationObject.t<ReactNative.Style.size>=?,
~top: AnimationObject.t<ReactNative.Style.size>=?,
~width: AnimationObject.t<ReactNative.Style.size>=?,
unit,
) => t = ""
}
type springOptions = {
damping: float,
mass: float,
stiffness: float,
overshootClamping: bool,
restDisplacementThreshold: float,
restSpeedThreshold: float,
}
let defaultSpringOptions = {
damping: 10.,
mass: 1.,
stiffness: 100.,
overshootClamping: false,
restDisplacementThreshold: 0.001,
restSpeedThreshold: 0.001,
}
@bs.scope("default") @bs.module("react-native-reanimated")
external interpolateColor: (
float,
array<float>,
array<ReactNative.Color.t>,
) => ReactNative.Color.t = "interpolateColor"
@bs.scope("default") @bs.module("react-native-reanimated")
external withSpring: (float, springOptions) => AnimationObject.t<float> = "withSpring"
@bs.scope("default") @bs.module("react-native-reanimated")
external withSpringColor: (
ReactNative.Color.t,
springOptions,
) => AnimationObject.t<ReactNative.Color.t> = "withSpring"
@bs.scope("default") @bs.module("react-native-reanimated")
external useSharedValue: ('a, ~shouldRebuild: bool=?) => SharedValue.t<'a> = "useSharedValue"
type animatedStyleArg = unit => AnimatedStyle.t
@bs.scope("default") @bs.module("react-native-reanimated")
external useAnimatedStyle: animatedStyleArg => ReactNative.Style.t = "useAnimatedStyle"
@bs.scope("default") @bs.module("react-native-reanimated")
external useAnimatedStyle1: (animatedStyleArg, array<'a>) => ReactNative.Style.t =
"useAnimatedStyle"
@bs.scope("default") @bs.module("react-native-reanimated")
external interpolate2: (
float,
(float, float),
(float, float),
~extrapolate: Extrapolate.t=?,
unit,
) => float = "interpolate"
@bs.scope("default") @bs.module("react-native-reanimated")
external interpolate3: (
float,
(float, float, float),
(float, float, float),
~extrapolate: Extrapolate.t=?,
unit,
) => float = "interpolate"
// you can assign an animated object to a shared value.
// it will perform some magic, so that the value will not actually be changed
// the type will also not change, it will just animate the value over time
// so it's not actually assignment. So we need a helper function for this.
let assignAnimatedObject = (
sharedValue: SharedValue.t<'a>,
animatedObject: AnimationObject.t<'a>,
) => sharedValue.value = Obj.magic(animatedObject)
type scrollEventFn = ReactNative.Event.scrollEvent => unit
@scope("default") @module("react-native-reanimated")
external useAnimatedScrollHandler: scrollEventFn => scrollEventFn = "useAnimatedScrollHandler"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment