Skip to content

Commit

Permalink
Docs [1] change of naming pattern (#3171)
Browse files Browse the repository at this point in the history
## Description

I changed the pattern of names, for example: `2.3.0 -> 2.3.x` because we publish documentation only for minor versions.
  • Loading branch information
piaskowyk authored May 12, 2022
1 parent 6cc151d commit 9a98696
Show file tree
Hide file tree
Showing 205 changed files with 5,068 additions and 144 deletions.
104 changes: 104 additions & 0 deletions docs/docs/api/hooks/useAnimatedSensor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
id: useAnimatedSensor
title: useAnimatedSensor
sidebar_label: useAnimatedSensor
---

With the `useAnimatedSensor` hook, you can easily create cool interactive animations based on data from sensors in the device such as gyroscope, accelerometer etc.

```js
useAnimatedSensor(sensorType: [SensorType], config?: [UserConfig]) -> [AnimatedSensor]
```

### Arguments

#### `sensorType` - [[SensorType](#sensortype-enum)]
You can select the sensor available in [[SensorType](#sensortype-enum)] enum.

#### `config` - [[UserConfig](#userconfig-object)]
Optionally, you can pass configuration to customize the sensor behavior.

### Returns
Hook `useAnimatedSensor` returns an instance of [[AnimatedSensor](#animatedsensor-object)];

### Types

#### `AnimatedSensor: [object]`
Properties:
* `sensor`: [[SharedValue](../../api/hooks/useSharedValue)] contains [[3DVector](#3dvector-object)] or [[RotationVector](#rotationvector-object)] or `null`
contains actual sensor measurements as a shared value
* `unregister: [function]`
allows you to stop listening to sensor updates
* `isAvailable: [boolean]`
the flag contains information on the availability of sensors in a device
* `config`: [[UserConfig](#userconfig-object)]
the configuration provided by a user

#### `SensorType: [enum]`
`SensorType` is an enum that contains possibly supported sensors.
Values:
* `ACCELEROMETER`
measurements output as [[3DVector](#3dvector-object)]
* `GYROSCOPE`
measurements output as [[3DVector](#3dvector-object)]
* `GRAVITY`
measurements output as [[3DVector](#3dvector-object)]
* `MAGNETIC_FIELD`
measurements output as [[3DVector](#3dvector-object)]
* `ROTATION`
measurements output as [[RotationVector](#rotationvector-object)]

#### `UserConfig: [object]`
Properties:
* `interval: [number]` - interval in milliseconds between shared value updates

#### `3DVector: [object]`
Properties:
* `x: number`
* `y: number`
* `z: number`

#### `RotationVector: [object]`
Properties:
* `qw: number`
* `qx: number`
* `qy: number`
* `qz: number`
* `yaw: number`
* `pitch: number`
* `roll: number`

### Example
```js
function UseAnimatedSensorExample() {
const animatedSensor = useAnimatedSensor(SensorType.ROTATION, { interval: 10 }); // <- initialization
const style = useAnimatedStyle(() => {
const yaw = Math.abs(animatedSensor.sensor.value.yaw);
const pitch = Math.abs(animatedSensor.sensor.value.pitch);
return {
height: withTiming(yaw * 200 + 20, { duration: 100 }), // <- usage
width: withTiming(pitch * 200 + 20, { duration: 100 }), // <- usage
};
});

return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Animated.View
style={[{ backgroundColor: 'black' }, style]}
/>
</View>
);
}
```

### Live example

<video src="https://user-images.githubusercontent.com/36106620/158634922-eaad656e-c837-44d5-8d51-8e7fa27c5a16.mp4" controls="controls" muted="muted" width="400"></video>

### Tips

:::caution

On iOS, if you want to read sensor data you need to enable location services on your device (`Settings > Privacy > Location Services`).

:::
1 change: 1 addition & 0 deletions docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module.exports = {
'api/hooks/useAnimatedStyle',
'api/hooks/useDerivedValue',
'api/hooks/useAnimatedScrollHandler',
'api/hooks/useAnimatedSensor',
'api/hooks/useAnimatedGestureHandler',
'api/hooks/useAnimatedRef',
'api/hooks/useAnimatedReaction',
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
---
id: customAnimations
title: Custom Animations
sidebar_label: Custom Animations
---

If our set of predefined animations is not enough for you then this tab is what you are looking for.

## Custom Exiting Animation

What our exiting animation builders do under the hood is generating a worklet function that returns essential data for starting particular animation.
The high level template looks like this:

```js
function CustomExitingAnimation(values) {
'worklet'
const animations = {
// your animations
};
const initialValues = {
// initial values for animations
};
const callback = (finished: boolean) => {
// optional callback that will fire when layout animation ends
};
return {
initialValues,
animations,
callback,
}
}
```

* `values` - contains information about where view was displayed and what were its dimensions
* `values.currentOriginX` - X coordinate of top left corner in parent's coordinate system
* `values.currentOriginY` - Y coordinate of top left corner in parent's coordinate system
* `values.currentWidth` - view's width
* `values.currentHeight` - view's height
* `values.currentGlobalOriginX` - X coordinate of top left corner in global coordinate system
* `values.currentGlobalOriginY` - Y coordinate of top left corner in global coordinate system

### Example
```js

function CardView() {
const exiting = (values) => {
'worklet';
const animations = {
originX: withTiming(width, { duration: 3000 }),
opacity: withTiming(0.5, { duration: 2000 }),
};
const initialValues = {
originX: values.currentOriginX,
opacity: 1,
};
return {
initialValues,
animations,
}
}


return (
<Animated.View
style={[styles.animatedView]} exiting={exiting} >
<Text> Card Example </Text>
</Animated.View>
);
}

```

## Custom Entering Animation

What our entering animation builders do under the hood is generating a worklet function that returns essential data for starting particular animation.
The high level template looks like this:

```js
function CustomEnteringAnimation(values) {
'worklet'
const animations = {
// your animations
};
const initialValues = {
// initial values for animations
};
const callback = (finished: boolean) => {
// optional callback that will fire when layout animation ends
};
return {
initialValues,
animations,
callback,
}
}
```

* `values` - contains information about where view wants to be displayed and what are its dimensions
* `values.targetOriginX` - X coordinate of top left corner in parent's coordinate system
* `values.targetOriginY` - Y coordinate of top left corner in parent's coordinate system
* `values.targetWidth` - view's width
* `values.targetHeight` - view's height
* `values.targetGlobalOriginX` - X coordinate of top left corder in global coordinate system
* `values.targetGlobalOriginY` - Y coordinate of top left corder in global coordinate system

### Example
```js

function CardView() {
const entering = (targetValues) => {
'worklet';
const animations = {
originX: withTiming(targetValues.originX, { duration: 3000 }),
opacity: withTiming(1, { duration: 2000 }),
borderRadius: withDelay(4000, withTiming(30, { duration: 3000 })),
transform: [
{ rotate: withTiming('0deg', { duration: 4000 }) },
{ scale: withTiming(1, { duration: 3500 }) },
],
};
const initialValues = {
originX: -width,
opacity: 0,
borderRadius: 10,
transform: [{ rotate: '90deg' }, { scale: 0.5 }],
};
return {
initialValues,
animations,
};
};


return (
<Animated.View
style={[styles.animatedView]} entering={entering} >
<Text> Card Example </Text>
</Animated.View>
);
}

```

## Custom Layout Transtion

What our layout transition builders do under the hood is generating a worklet function that returns essential data for starting particular transition.
The high level template looks like this:

```js
function CustomLayoutTransition(values) {
'worklet'
const animations = {
// your animations
};
const initialValues = {
// initial values for animations
};
const callback = (finished: boolean) => {
// optional callback that will fire when layout animation ends
};
return {
initialValues,
animations,
callback,
}
}
```

* `values` - contains before and after information about the view's origin and dimensions
* `values.targetOriginX` - X coordinate of top left corner in parent's coordinate system
* `values.targetOriginY` - Y coordinate of top left corner in parent's coordinate system
* `values.targetWidth` - view's width
* `values.targetHeight` - view's height
* `values.targetGlobalOriginX` - X coordinate of top left corder in global coordinate system
* `values.targetGlobalOriginY` - Y coordinate of top left corder in global coordinate system
* `values.currentOriginX` - X coordinate of top left corner in parent's coordinate system (before)
* `values.currentOriginY` - Y coordinate of top left corner in parent's coordinate system (before)
* `values.currentWidth` - view's width (before)
* `values.currentHeight` - view's height (before)
* `values.currentGlobalOriginX` - X coordinate of top left corner in global coordinate system (before)
* `values.currentGlobalOriginY` - Y coordinate of top left corner in global coordinate system (before)

### Example
<video src="https://user-images.githubusercontent.com/12784455/120450759-09fa3980-c391-11eb-9b64-65ec8e6c2509.mp4" controls="controls" muted="muted" width="45%"></video>

```js

function CustomLayoutTransition(values) {
'worklet'
return {
animations: {
originX: withTiming(values.targetOriginX, {duration: 1000}),
originY: withDelay(1000, withTiming(values.targetOriginY, {duration: 1000})),
width: withSpring(values.targetWidth),
height: withSpring(values.targetHeight),
},
initialValues: {
originX: values.currentOriginX,
originY: values.currentOriginY,
width: values.currentWidth,
height: values.currentHeight,
}
};
}

function Box({label, state}: {label: string, state: boolean}) {
const ind = label.charCodeAt(0) - ('A').charCodeAt(0);
const delay = 300 * ind;
return (
<Animated.View
layout={CustomLayoutTransition}
style={[styles.box,
{
flexDirection: (state)? 'row': 'row-reverse',
height: (state)? 30: 60,
}]}
>
<Text> {label} </Text>
</Animated.View>
);
}

export function CustomLayoutTransitionExample(): React.ReactElement {
const [state, setState] = useState(true);
return (
<View style={{marginTop: 30}} >
<View style={{height: 300}} >
<View style={{flexDirection: state? 'row' : 'column'}} >
{state && <Box key="a" label="A" state={state} />}
<Box key="b" label="B" state={state} />
{!state && <Box key="a" label="A" state={state} />}
<Box key="c" label="C" state={state} />
</View>
</View>

<Button onPress={() => {setState(!state)}} title="toggle" />
</View>
);
}


```

## Other Facts

Each Reanimated component has its shared value that keeps current animations assigned to that particular component. If you want to start a new animation for a specific prop and you don't provide an initial value for the prop then the initial value will be taken from the last animation that has been assigned to the component. The only exception is Entering animation because we have no way to get the previous animation values.
Loading

0 comments on commit 9a98696

Please sign in to comment.