Skip to content
This repository has been archived by the owner on Aug 9, 2023. It is now read-only.

Port scroll-related pages from old docs #34

Merged
merged 4 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/advanced/_category_.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"label": "Advanced APIs",
"position": 5,
"position": 6,
"link": {
"type": "generated-index"
}
Expand Down
4 changes: 2 additions & 2 deletions docs/advanced/measure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ interface MeasuredDimensions {
}

function measure<T extends Component>(
animatedRef: RefObject<T>
animatedRef: AnimatedRef<T>
): MeasuredDimensions | null;
```

Expand All @@ -53,7 +53,7 @@ function measure<T extends Component>(

#### `animatedRef`

An [animated ref](/) connected to the component you'd want to get the measurements from. The animated ref has to be passed either to an [Animated component](/docs/fundamentals/glossary#animated-component) or a React Native built-in component.
An [animated ref](/docs/advanced/useAnimatedRef#returns) connected to the component you'd want to get the measurements from. The animated ref has to be passed either to an [Animated component](/docs/fundamentals/glossary#animated-component) or a React Native built-in component.

### Returns

Expand Down
2 changes: 1 addition & 1 deletion docs/advanced/useAnimatedRef.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ sidebar_position: 2

# useAnimatedRef

`useAnimatedRef` lets you get a reference of a view. Used alongside [`measure`](/docs/advanced/measure), `scrollTo`, and `useScrollViewOffset` functions.
`useAnimatedRef` lets you get a reference of a view. Used alongside [`measure`](/docs/advanced/measure), [`scrollTo`](/docs/scroll/scrollTo), and [`useScrollViewOffset`](/docs/scroll/useScrollViewOffset) functions.

An object defined using `useAnimatedRef` has to be passed to the `ref` property of a component.

Expand Down
2 changes: 1 addition & 1 deletion docs/layout-animations/_category_.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"label": "Layout Animations",
"position": 4,
"position": 5,
"link": {
"type": "generated-index"
}
Expand Down
7 changes: 7 additions & 0 deletions docs/scroll/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"label": "Scroll",
"position": 4,
"link": {
"type": "generated-index"
}
}
111 changes: 111 additions & 0 deletions docs/scroll/scrollTo.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
sidebar_position: 1
---

# scrollTo

:::info
This page was ported from an old version of the documentation.

As we're rewriting the documentation some of the pages might be a little outdated.
:::

Provides synchronous scroll on the UI thread to a given offset using an animated ref to a scroll view. This allows performing smooth scrolling without lags (which might have otherwise occurred when it was asynchronous and based on lots of events).

### Arguments

#### `animatedRef`

The product of [`useAnimatedRef`](/docs/advanced/useAnimatedRef) which is Reanimated's extension of a standard React ref (delivers the view tag on the UI thread).

#### `x` [Float]

Corresponds to the pixel along the horizontal axis of the element that you want displayed in the upper left.

#### `y` [Float]

Corresponds to the pixel along the vertical axis of the element that you want displayed in the upper left.

#### `animated` [Boolean]

Indicates whether the scroll should be smooth (`true`) or instant (`false`).

### Returns

`void`

### Example

```jsx
import React from "react";
import { TouchableOpacity, View, Text, ScrollView } from "react-native";
import {
useAnimatedRef,
useDerivedValue,
useSharedValue,
scrollTo,
} from "react-native-reanimated";

const ITEM_COUNT = 10;
const ITEM_SIZE = 100;
const ITEM_MARGIN = 10;

export const Comp = () => {
const aref = useAnimatedRef();
const scroll = useSharedValue(0);

useDerivedValue(() => {
scrollTo(aref, 0, scroll.value * (ITEM_SIZE + 2 * ITEM_MARGIN), true);
});

const items = Array.from(Array(ITEM_COUNT).keys());

const Incrementor = ({ increment }) => (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<TouchableOpacity
onPress={() => {
scroll.value =
scroll.value + increment > 0
? scroll.value + increment
: ITEM_COUNT - 1 + increment;

if (scroll.value >= ITEM_COUNT - 2) scroll.value = 0;
}}
>
<Text>{`Scroll ${Math.abs(increment)} ${
increment > 0 ? "down" : "up"
}`}</Text>
</TouchableOpacity>
</View>
);

return (
<View style={{ flex: 1, flexDirection: "column" }}>
<Incrementor increment={1} />
<View
style={{ width: "100%", height: (ITEM_SIZE + 2 * ITEM_MARGIN) * 2 }}
>
<ScrollView ref={aref} style={{ backgroundColor: "orange" }}>
{items.map((_, i) => (
<View
key={i}
style={{
backgroundColor: "white",
aspectRatio: 1,
width: ITEM_SIZE,
margin: ITEM_MARGIN,
justifyContent: "center",
alignContent: "center",
}}
>
<Text style={{ textAlign: "center" }}>{i}</Text>
</View>
))}
</ScrollView>
</View>

<Incrementor increment={-1} />
</View>
);
};
```
127 changes: 127 additions & 0 deletions docs/scroll/useAnimatedScrollHandler.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
---
sidebar_position: 3
---

# useAnimatedScrollHandler

:::info
This page was ported from an old version of the documentation.

As we're rewriting the documentation some of the pages might be a little outdated.
:::

This is a convenience hook that returns an event handler reference which can be used with React Native's scrollable components.

### Arguments

#### `scrollHandlerOrHandlersObject` [object with worklets]

Object containing any of the following keys: `onScroll`, `onBeginDrag`, `onEndDrag`, `onMomentumBegin`, `onMomentumEnd`.
The values in the object should be individual worklets.
Each of the worklet will be triggered when the corresponding event is dispatched on the connected Scrollable component.

Each of the event worklets will receive the following parameters when called:

- `event` [object] - event object carrying the information about the scroll.
The payload can differ depending on the type of the event (`onScroll`, `onBeginDrag`, etc.).
Please consult [React Native's ScrollView documentation](https://reactnative.dev/docs/scrollview) to learn about scroll event structure.

- `context` [object] - plain JS object that can be used to store some state.
This object will persist in between scroll event occurrences and you can read and write any data to it.
When there are several event handlers provided in a form of an object of worklets, the `context` object will be shared in between the worklets allowing them to communicate with each other.

#### `dependencies` [Array]

Optional array of values which changes cause this hook to receive updated values during rerender of the wrapping component. This matters when, for instance, worklet uses values dependent on the component's state.

Example:

```js {11}
const App = () => {
const [state, setState] = useState(0);
const sv = useSharedValue(0);

const handler = useAnimatedScrollHandler(
{
onEndDrag: (e) => {
sv.value = state;
},
},
dependencies
);
//...
return <></>;
};
```

`dependencies` here may be:

- `undefined`(argument skipped) - worklet will be rebuilt if there is any change in any of the callbacks' bodies or any values from their closure(variables from outer scope used in worklet),
- empty array(`[]`) - worklet will be rebuilt only if any of the callbacks' bodies changes,
- array of values(`[val1, val2, ..., valN]`) - worklet will be rebuilt if there is any change in any of the callbacks bodies or in any values from the given array.

### Returns

The hook returns a handler object that can be hooked into a scrollable container.
Note that in order for the handler to be properly triggered, you should use containers that are wrapped with `Animated` (e.g. `Animated.ScrollView` and not just `ScrollView`).
The handler should be passed under `onScroll` parameter regardless of whether it is configured to receive only scroll or also momentum or drag events.

## Example

In the below example we define a scroll handler by passing a single worklet handler.
The worklet handler is triggered for each of the scroll events dispatched to the `Animated.ScrollView` component to which we attach the handler.

```jsx {10-12,29}
import Animated, {
useSharedValue,
useAnimatedStyle,
useAnimatedScrollHandler,
} from "react-native-reanimated";

function ScrollExample() {
const translationY = useSharedValue(0);

const scrollHandler = useAnimatedScrollHandler((event) => {
translationY.value = event.contentOffset.y;
});

const stylez = useAnimatedStyle(() => {
return {
transform: [
{
translateY: translationY.value,
},
],
};
});

return (
<View style={styles.container}>
<Animated.View style={[styles.box, stylez]} />
<Animated.ScrollView style={styles.scroll} onScroll={scrollHandler}>
<Content />
</Animated.ScrollView>
</View>
);
}
```

If we are interested in receiving drag or momentum events instead of passing a single worklet object we can pass an object of worklets.
Below for convenience, we only show how the `scrollHandler` should be defined in such a case.
The place where we attach handler to a scrollable component remains unchanged regardless of the event types we want to receive:

```jsx
const isScrolling = useSharedValue(false);

const scrollHandler = useAnimatedScrollHandler({
onScroll: (event) => {
translationY.value = event.contentOffset.y;
},
onBeginDrag: (e) => {
isScrolling.value = true;
},
onEndDrag: (e) => {
isScrolling.value = false;
},
});
```
61 changes: 61 additions & 0 deletions docs/scroll/useScrollViewOffset.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
sidebar_position: 2
---

# useScrollViewOffset

:::info
This page was ported from an old version of the documentation.

As we're rewriting the documentation some of the pages might be a little outdated.
:::

This hook allows you to create animations based on the offset of a `ScrollView`.
The hook automatically detects if the `ScrollView` is horizontal or vertical.

```ts
useScrollViewOffset(aref: RefObject<Animated.ScrollView>) => [SharedValue<number>]
```

### Arguments

#### `aref` [RefObject&lt;Animated.ScrollView&gt;]

An Animated reference to a `ScrollView`. The reference should be passed to the
appropriate `ScrollView` in the `ref` prop.

### Returns

A shared value which holds the current offset of the `ScrollView`.

## Example

```jsx
function ScrollViewOffsetExample() {
const aref = useAnimatedRef<Animated.ScrollView>();
const scrollHandler = useScrollViewOffset(aref);

useAnimatedStyle(() => {
console.log(scrollHandler.value);
return {};
});

return (
<>
<View style={styles.positionView}>
<Text>Test</Text>
</View>
<View style={styles.divider} />
<Animated.ScrollView
ref={aref}
style={styles.scrollView}>
{[...Array(100)].map((_, i) => (
<Text key={i} style={styles.text}>
{i}
</Text>
))}
</Animated.ScrollView>
</>
);
}
```
2 changes: 1 addition & 1 deletion docs/threading/_category_.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"label": "Threading",
"position": 6,
"position": 7,
"link": {
"type": "generated-index"
}
Expand Down