Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@kuba/docs #459

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
255bb7b
Add docs website
osdnk May 6, 2019
80ed796
Fix typo
osdnk May 6, 2019
fb56016
Remove useless things
osdnk May 7, 2019
376d57e
Remove callstack
osdnk May 8, 2019
a5d0d99
Remove bad import
osdnk May 8, 2019
be78bff
Add logo and fix
osdnk May 8, 2019
62c83a5
Fix default page
osdnk May 9, 2019
b72f231
Remove useless styles
osdnk May 9, 2019
6a61347
README Re-write (#178)
esthor May 10, 2019
62e9d99
conform with merged PR
jkadamczyk May 10, 2019
1266aae
make formatting more uniform
jkadamczyk May 10, 2019
36583ed
minor typos
jkadamczyk May 10, 2019
c805171
unnecessaryc haracter
jkadamczyk May 10, 2019
7d897dd
comma
jkadamczyk May 10, 2019
158a75b
H2
jkadamczyk May 10, 2019
e206f51
clean character errors
jkadamczyk May 10, 2019
c1ba396
split nodes and animations into separate
jkadamczyk May 13, 2019
3696198
Your -> your
osdnk May 13, 2019
5c9a182
Remove logo
osdnk May 13, 2019
eae1786
make this work with node 10
jkadamczyk May 13, 2019
cee13fd
delete polyfill implement flat by hand
jkadamczyk May 13, 2019
376cc07
Rewrite README.md
osdnk May 13, 2019
eef26ee
Format pages
jakub-gonet Nov 9, 2019
0a5633d
Format and update 04.transitions.md
jakub-gonet Nov 8, 2019
1caa224
Format and update 05.value.md
jakub-gonet Nov 8, 2019
d8e8b22
Format and update 07.block.md
jakub-gonet Nov 8, 2019
8f4db88
Format and update 09.code.md
jakub-gonet Nov 8, 2019
026e1fe
Format and update 10.event.md
jakub-gonet Nov 8, 2019
97d958e
Add 11.baseNodes/log.md
jakub-gonet Nov 8, 2019
d4d6612
Format and update 11.baseNodes/floor.md
jakub-gonet Nov 8, 2019
c0a6d4c
Format and update 11.baseNodes/ceil.md
jakub-gonet Nov 8, 2019
cdfdb78
Format and update 11.baseNodes/set.md
jakub-gonet Nov 8, 2019
c68ed43
Update min, max docs
jakub-gonet Nov 8, 2019
2aa95ba
Add proc node docs
jakub-gonet Nov 8, 2019
cc8fb68
Update README.md with latest version
jakub-gonet Nov 9, 2019
5ea8ac0
Remove unnecessary assets folders
jakub-gonet Nov 9, 2019
9c53394
Update README.md
jakub-gonet Nov 9, 2019
3ce300e
Remove meme
jakub-gonet Nov 9, 2019
1dd2917
Fix links and move 14.backward.md to 13.declarative.md
jakub-gonet Nov 9, 2019
bf7a0c5
Remove 1st person narrative in about page
jakub-gonet Nov 9, 2019
a3ee267
Remove assets/ from component-docs config
jakub-gonet Nov 9, 2019
3f4af13
Update yarn.lock
jakub-gonet Nov 9, 2019
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
918 changes: 25 additions & 893 deletions README.md

Large diffs are not rendered by default.

Binary file removed assets/meme.png
Binary file not shown.
2 changes: 2 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
.linaria-cache/
15 changes: 15 additions & 0 deletions docs/assets/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
a,
a:hover {
color: #6200ee;
}

a:hover {
color: #873df2;
}


@font-face {
font-family: 'MaterialIcons';
src: url('../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf')
format('truetype');
}
75 changes: 75 additions & 0 deletions docs/component-docs.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* @flow */

import path from 'path';
import fs from 'fs';

Object.defineProperty(Array.prototype, 'flat', {
value: function(depth = 1) {
return this.reduce(function(flat, toFlatten) {
return flat.concat(
Array.isArray(toFlatten) && depth > 1
? toFlatten.flat(depth - 1)
: toFlatten
);
}, []);
},
});

const root = path.join(__dirname, '..');
const dist = path.join(__dirname, 'dist');
const styles = [path.join(__dirname, 'assets', 'styles.css')];
const github =
'https://github.com/kmagiera/react-native-reanimated/edit/master/';

if (!fs.existsSync(dist)) {
fs.mkdirSync(dist);
}

function getType(file: string) {
if (file.endsWith('.js')) {
return 'custom';
} else if (file.endsWith('.mdx')) {
return 'mdx';
}
return 'md';
}

const nameToGroupTitle = (name: string) => {
return name
.split('.')[1]
.split(/(?=[A-Z])/)
.map(s => s.charAt(0).toUpperCase() + s.slice(1))
.join(' ');
};

const mapToObject = (filePath, group) =>
fs
.readdirSync(filePath, { withFileTypes: true })
.map(file => {
if (file.isDirectory()) {
return mapToObject(
path.join(filePath, file.name),
nameToGroupTitle(file.name)
);
} else {
let result = {
file: path.join(filePath, file.name),
type: getType(file.name),
};
if (!!group) {
result['group'] = group;
}
return result;
}
})
.flat();

const docs = mapToObject(path.join(__dirname, 'pages'));

module.exports = {
root,
styles,
pages: docs,
output: dist,
github,
};
30 changes: 30 additions & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "react-native-reanimated",
"version": "0.0.1",
"description": "Documentation for React Native Reanimated",
"private": true,
"scripts": {
"start": "component-docs serve",
"build": "component-docs build",
"clean": "del dist/",
"prestart": "yarn clean"
},
"devDependencies": {
"@babel/node": "^7.2.2",
"@babel/plugin-proposal-class-properties": "^7.2.3",
"@babel/preset-env": "^7.2.3",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"del-cli": "^1.1.0",
"file-loader": "^1.1.11",
"url-loader": "^1.0.1"
},
"author": "",
"license": "MIT",
"dependencies": {
"color": "^2.0.1",
"component-docs": "^0.19.5",
"linaria": "^1.2.4",
"react-native-vector-icons": "^6.4.2"
}
}
18 changes: 18 additions & 0 deletions docs/pages/01.index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: React Native Reanimated
link: index
---

# React Native Reanimated

React Native's Animated library reimplemented.

- **Native Performance**: Declare your animations in JS, but have them run on the native thread! 🧙‍♂️
- **Precise Animations**: The API affords new levels of precision and detailed control of your animations. 🕹
- **(mostly) Backwards Compatible**: Use the same Animated API from React Native that you've been using. You generally don't _need_ to change anything to get started. 👍

Reanimated provides a more comprehensive, low level abstraction for the Animated library API, giving you much greater flexibility, control and performance. Combine it with [react-native-gesture-handler](https://github.com/kmagiera/react-native-gesture-handler) for performant gesture-based interactions.

## Want to contribute?

Head over right [there](https://github.com/kmagiera/react-native-reanimated), we are open for your pull requests!
57 changes: 57 additions & 0 deletions docs/pages/02.about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: About Reanimated
---

# Motivation

---

`Animated` library has several limitations that become troubling when it comes to gesture based interactions.
This project was initially created to resolve the issue of pan interaction when the object can be dragged along the screen and when released it should snap to some place on the screen.
The problem was that despite using `Animated.event` and mapping gesture state to the position of the box, and making this whole interaction run on UI thread with `useNativeDriver` flag, we still had to call back into JS at the end of the gesture for us to start "snap" animation.
This is because `Animated.spring({}).start()` cannot be used in a "declarative" manner, because when it gets executed it has a "side effect" of starting a process (an animation) that updates the value for some time.
Adding "side effect" nodes into the current Animated implementation turned out to be a pretty difficult task as the execution model of the Animated API runs all the dependent nodes of each frame for the views that need to update.
We don't want to run "side effects" more often than necessary as it would, for example, result in the animation starting multiple times.

Another inspiration to redesigning the internals of `Animated` was Krzysztof's work on porting "Animated Tracking" functionality to the native driver.
Apparently, even though the native driver is out for quite a while, it still does not support all the things non-native `Animated` lib can do.
Obviously, it is far more difficult to build three versions of each feature (JS, Android and iOS) instead of one, and the same applies for fixing bugs.
One of the goals of `react-native-reanimated` was to provide a more generic building block for the API that would allow for building more complex features only in JS and make the native codebase as minimal as possible.
Taking "diffClamp" node as an example, it is currently implemented in three different places in `Animated` core and even though it is pretty useful it actually only has one use case (collapsible scrollview header).

On a similar topic, there's React Native's PR [#18029](https://github.com/facebook/react-native/pull/18029) and even though it provides a legitimate use case, maintainers are hesitant about merging it. The `Animated` API shouldn't block people from building things like this and the goal of `react-native-reanimated` is to provide lower level access that would allow for implementing that and many more features with no necessary changes to the core of the library.

You can watch Krzysztof Magiera's [React Europe talk](https://www.youtube.com/watch?v=kdq4z2708VM) where he explains the motivation.

The goals:

- More generic primitive node types leading to more code reuse for the library internals therefore making it easier to add new features and fix bugs.
- The new set of base nodes can be used to implement `Animated` compatible API including:
- Complex nodes such as “diffClamp”.
- Interactions such as animated value tracking or animation staggering.
- Conditional evaluation & nodes with side effects (`set`, `startClock`, `stopClock`).
- No more “useNativeDriver” – all animations runs on the UI thread by default

# Reanimated overview

We aim to bring this project to be fully compatible with `Animated` API. We believe that the set of base nodes we have selected should make this possible to be done only by writing JS code and does not require significant changes in the native codebases. Here is a list of things that haven't yet been ported from the original version of `Animated` library.
All the functionality that missing elements provide in `Animated` can already be achieved with `react-native-reanimated` although a different methodology for implementing those may be required (e.g. check ["Declarative Animation API" section](declarative-animation-api.html) to see how the implementation may differ).

- [ ] using value offsets
- [ ] value tracking (can be achieved in different way, `react-native-reanimated` also allows for tracking all the animation parameters not only destination params)
- [ ] animation staggering
- [ ] animation delays

# At most once evaluation (the algorithm)

Unlike the original `Animated` library where each node could have been evaluated many times within a single frame, `react-native-reanimated` restricts each node to be evaluated at most once in a frame.
This restriction is required for nodes that have side-effects to be used (e.g. [`set`](set.html) or [`startClock`](start-clock.html)).
When node is evaluated (e.g. in case of an [`add`](add.html) node we want to get a sum of the input nodes) its value is cached. If within the next frame there are other nodes that want to use the output of that node instead of evaluating we return cached value.
This notion also helps with performance as we can try to evaluate as few nodes as expected.
The current algorithm for making decisions of which nodes to evaluate works as follows:

1. For each frame we first analyze the generated events (e.g. touch stream). It is possible that events may update some animated values.
2. Then we update values that correspond to [clock](clock-and-the-algorithm.html) nodes that are "running".
3. We traverse the node's tree starting from the nodes that have been updated in the current cycle and we look for final nodes that are connected to views.
4. If we found nodes connected to view properties we evaluate them. This can recursively trigger an evaluation for their input nodes etc.
5. After everything is done we check if some "running" clocks exists. If so we enqueue a callback to be evaluated with the next frame and start over from pt 1. Otherwise we do nothing.
39 changes: 39 additions & 0 deletions docs/pages/03.start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: Getting Started
---

# Getting started

---

Before you get started you should definitely familiarize yourself with the original [Animated API](https://facebook.github.io/react-native/docs/animated.html). It will do you well to be comfortable with how animations are generally done in `Animated`. (Fun Fact: Reanimated is also backwards compatible with the `Animated API`. 🙌)

Refer to the [Motivation](about-reanimated.html#Motivation---OMG,-why-would-you-build-this?) section to understand why this library exists

NOTE: Throughout this document when we refer to classes or methods prefixed with `Animated` we are referring to them being imported from `react-native-reanimated` package instead of plain `react-native`, unless otherwise stated.

## Installation

I. First install the library from npm repository using `yarn`:

```bash
yarn add react-native-reanimated
```

II. Link native code with `react-native` cli:

```bash
react-native link react-native-reanimated
```

III. When you want to use "reanimated" in your project import it from the `react-native-reanimated` package:

```js
import Animated from 'react-native-reanimated';
```

Similarly when you need `Easing` import it from the `react-native-reanimated` package instead of `react-native`:

```js
import Animated, { Easing } from 'react-native-reanimated';
```
61 changes: 61 additions & 0 deletions docs/pages/04.transitions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
title: Transitions
---

# Transitions

---

Transitions is an experimental API distributed as a part of reanimated which serves the purpose of animating between two states of view hierarchy. It is conceptually similar to `LayoutAnimation` concept from react native but gives much better control of what and how is going to be animated.

Transitions API consists of two main building blocks. First one being `Transitioning.View` which is an extension of regular react-native view, so you can use any `View` props you'd like. The `Transitioning.View` is a root of all the transition animations that will be happening and is used to scope the changes to its children. In order to have next transition animated you'd need to call `animateNextTransition()` on the `Transitioning.View` instance.

The second main building block is transition definition. Transitioning API uses JSX syntax that allows you to define how the transition animation should perform. You can use all the components from `Transition` object to combine the animation you want. Please see the below list for the documentation of transition components.

## Transition groups

The below set of components can be used to group one or more transitions. You can also nest transition groups in order to achieve desirable effects.

### `<Transition.Together>`

Transitions nested under this component will run in parallel when the animation starts.

### `<Transition.Sequence>`

Transitions nested under this component will run in sequence in the order at which they are listed

## Transitions

Transition components can be used separately or as a part of a group. Each transition component has the following common properties you can use to configure the animation:

#### `durationMs`

The time animation takes to execute in milliseconds

#### `delayMs`

Use this if you want the animation to start delayed (value in milliseconds)

#### `interpolation`

Specify the transition timing curve. Possible values are: `linear`, `easeIn`, `easeOut`, `easeInOut`

#### `propagation`

Allows for the framework to automatically delay beginning of transitions across a set of different views depending on their position. The possible values are `top`, `bottom`, `left` and `right`. When `propagation="top"` it means that the first element that will start animating is the one that is closest to the top of `Transitioning.View` container, then the other views will be delayed by the amount which depends on their distance from the top edge.

### `<Transition.In>`

Allows to specify how views that get mounted during animation transition get animated. In addition to the above parameters you can specify the type of animation using `type` prop. The possible values are: `fade`, `scale`, `slide-top`, `slide-bottom`, `slide-left`, `slide-right`.

### `<Transition.Out>`

Allows to specify how the framework should animate views that are being removed during transition. In addition to the above parameters you can specify the type of animation using `type` prop. The possible values are: `fade`, `scale`, `slide-top`, `slide-bottom`, `slide-left`, `slide-right`.

### `<Transition.Change>`

Use `Transition.Change` component to specify how components' which properties get changed during transition should be animated. The framework currently supports an animating position, bounds and transforms.

## How to use it

This API is still experimental and is a subject to change. Please refer to our [Example app](https://github.com/kmagiera/react-native-reanimated/tree/master/Example/transitions) to see how it can be used in practice in the current shape.
15 changes: 15 additions & 0 deletions docs/pages/05.value.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Value
---

# Value

---

`Animated.Value` is a container for storing values. It's is initialized with `new Value(0)` constructor. For backward compatibility there are provided API for setting value after it has been initialized:

```js
const v = new Value(0);
/// ...
v.setValue(100);
```
15 changes: 15 additions & 0 deletions docs/pages/06.clock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Clock and the algorithm
---

# Clocks

---

Original `Animated` API makes an "animation" object a first class citizen.
`Animation` object has many features and therefore requires quite a few JS<>Native bridge methods to be managed properly.
In `react-native-reanimated`, clocks aim to replace that by providing more of a low level abstraction but also since clock nodes behave much like the animated values they make the implementation much less complex.

`Animated.Clock` node is a special type of `Animated.Value` that can be updated in each frame to the timestamp of the current frame. When we take `Clock` node as an input, the value it returns is the current frame timestamp in milliseconds. Using special methods, clock nodes can be stopped and started and we can also test if clock has been started.

Because `Animated.Clock` just extends the `Animated.Value` you can use it in the same places (operations) where you can pass any type of animated node.
19 changes: 19 additions & 0 deletions docs/pages/07.block.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: Block
---

# Blocks

---

Blocks are just arrays of nodes that are being evaluated in a particular order and return the value of the last node. It can be created using `block` command but also when passed as an argument to other nodes the `block` command can be omitted and we can just pass a nodes array directly. See an example below:

```js
cond(
eq(state, State.ACTIVE),
[stopClock(clock), set(transX, add(transX, diffX))],
runTiming(clock, state, config)
);
```

Passing array directly is equivalent to wrapping it with the `block` command.
19 changes: 19 additions & 0 deletions docs/pages/08.view.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: Views, props, etc
---

# Views, props, etc

---

Follow the original `Animated` library guides to learn how values can be connected to View attributes.
Similarly with `react-native-reanimated` you need to use components prefixed with `Animated.` (remember to [import](getting-started.html#installation) `Animated` from reanimated package). For example:

```js
import Animated from 'react-native-reanimated';

// use
<Animated.View/>
// instead of
<View/>
```
Loading