Coder Social home page Coder Social logo

software-mansion / react-native-reanimated Goto Github PK

View Code? Open in Web Editor NEW
8.4K 74.0 1.3K 217.81 MB

React Native's Animated library reimplemented

Home Page: https://docs.swmansion.com/react-native-reanimated/

License: MIT License

JavaScript 1.66% Java 8.69% Objective-C 5.15% Ruby 0.68% C++ 9.77% Objective-C++ 4.15% Shell 0.10% TypeScript 69.10% C 0.03% CMake 0.46% Kotlin 0.23%
animation gesture react-native javascript

react-native-reanimated's Introduction

React Native Reanimated by Software Mansion

React Native's Animated library reimplemented

Reanimated 3 is here! Check out our documentation page for more information

React Native Reanimated provides a more comprehensive, low level abstraction for the Animated library API to be built on top of and hence allow for much greater flexibility especially when it comes to gesture based interactions.

Nightly CI state

Build nightly npm package Run nightly monorepo test Check static framework nightly build Check React Native nightly build Check Expo dev-client nightly build Check TypeScript nightly build Test V8 on Android nightly Test build on Windows nightly Validate urls in source code

Installation

Check out the installation section of our docs for the detailed installation instructions.

Fabric

To learn how to use react-native-reanimated with Fabric architecture, head over to Fabric README. Instructions on how to run Fabric Example within this repo can be found in the FabricExample README.

Documentation

Check out our dedicated documentation page for info about this library, API reference and more: https://docs.swmansion.com/react-native-reanimated/

Examples

The source code for the example (showcase) app is under the Example/ directory. If you want to play with the API but don't feel like trying it on a real app, you can run the example project. Check Example/ directory README for installation instructions.

License

Reanimated library is licensed under The MIT License.

Credits

This project has been built and is maintained thanks to the support from Shopify, Expo.io and Software Mansion

shopify expo swm

react-native-reanimated's People

Contributors

bartlomiejbloniarz avatar dependabot[bot] avatar evanbacon avatar graszka22 avatar j-piasecki avatar jakub-gonet avatar janicduplessis avatar jfedak avatar jmysliv avatar jwajgelt avatar kacperkapusciak avatar karol-bisztyga avatar kkafar avatar kmagiera avatar kudo avatar kwasow avatar latropos avatar m-bert avatar michalmaka avatar mrousavy avatar mstach60161 avatar osdnk avatar piaskowyk avatar szydlovsky avatar terrysahaidak avatar tjzel avatar tomekzaw avatar wcandillon avatar wolewicki avatar xnametm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-reanimated's Issues

Cannot update props of Animated components after mount

Consider this simple sample:

import * as React from 'react';
import { StyleSheet, View } from 'react-native';
import Animated from 'react-native-reanimated';

export default class App extends React.Component {
  state = { iteration: 0 };

  componentDidMount() {
    setInterval(() => { this.setState(state => ({ iteration: state.iteration + 1 })) }, 500);
  }

  render() {
    const backgroundColor = ['red', 'green', 'blue'][this.state.iteration % 3];
    return (
      <View style={styles.container}>
        <Animated.View style={[styles.box, {backgroundColor}]} />
        <View style={[styles.box, {backgroundColor}]} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'white',
  },
  box: {
    width: 50,
    height: 50,
    marginBottom: 40
  }
});

Both boxes should have their background-color changed every 500ms. Unfortunately, it only works on the non-animated box as can be seen on the following image:
noupdateprops

Actually, any non-animated props change is ignored after the first render. I've tracked the issue down to this commit 881990b and especially the createOrReusePropsNode() that returns the old props if none of the animated props have changed.

dissimilar behaviour between ios and android

I was testing this demo:
https://snack.expo.io/@codedaily/reanimatedopacitybasics
That i encountered a problem.
Simply it shows a box at the center and as long you touch it, its opacity is reduced.
On ios everything works as expected.
But on android when you press and hold on the box, after 1 second the box opacity unexpectedly increases back to 1.
this demo uses react-native-reanimated and react-native-gesture-handler simultaneously.
I naively guessed this would be the proper repository to report the issue.
"react-native": "0.55.4",
"react-native-gesture-handler": "1.0.7",
"react-native-reanimated": "1.0.0-alpha.6"
Tested on device(Android 9) and simulator(Android 6) and latest expo app. Same results.

[Question] How to wait until clock finished

Hi, thanks for your work - real awesome library, I have a question:

In my example there are pan responder and card stack, when i swipe card to the left - it should animate out of screen, so the main problem that I have is block any gestures before clock/animation finished.

In all examples that i see - just stopClock, save position continue

Any advice please)?

Error: Non-extensible objects are not allowed as keys

Hi!

I'm using latest [email protected] and [email protected]. In some conditions I catch Error: Non-extensible objects are not allowed as keys (on Android emulator with API 26, don't know if reproducible on iOS or other API):

image

The easiest way to reproduce it is to add the following code to "image viewer" example:

componentDidMount() {
    this.forceUpdate();
}

The workaround is to move this._onPinchEvent and this._onPanEvent to render function, thus effectively recreating them on each render.

I hope this information would help you debugging and fixing this bug. #82 may be related.

Declarative onLayout

It would be a nice feature to add possibility to use onLayout in declarative way with Animated.Event and normal non-animated View

Content appears to be frozen inside Animated component

For some reason, updates to state and props don't seem to reach the contents of Animated.ScrollView. I can't reliably reproduce it, but it appears to be related to this issue: #27
As the issue only occurs together with that one.

Ideas?

Getting error "Event node is of an invalid type" when using event with react-native-gesture-handler.

Sorry for all the issues. This error happens when re-rendering a component.

Here's an example:

import React, { Component } from 'react';
import { StyleSheet, View, Text } from 'react-native';
import Animated, { Easing } from 'react-native-reanimated';
import { TapGestureHandler, State } from 'react-native-gesture-handler';

const {
  Value,
  event,
} = Animated;

export class Example extends Component {
  constructor(props) {
    console.log('constructor')
    super(props);
    const state = new Value(-1);
    this._onGestureEvent = event([
      { nativeEvent: { state } },
    ]);
  }
  render() {
    console.log('render')
    return (
      <View style={styles.container}>
        <TapGestureHandler onHandlerStateChange={this._onGestureEvent}>
          <Animated.View style={styles.toggle}>
            <Text style={styles.toggleText}>The Text</Text>
          </Animated.View>
        </TapGestureHandler>
      </View>
    );
  }
}

export default class TestingContainer extends Component {
  state = {
    count: 0,
  }
  increment = () => {
    this.setState(state => ({
      count: state.count + 1,
    }))
  }
  componentDidMount() {
    this.interval = setInterval(this.increment, 5000)
  }
  componentWillUnmount() {
    clearInterval(this.interval)
  }
  render() {
    return <Example count={this.state.count} />
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  toggle: {
    width: 100,
    height: 100,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'black',
    borderRadius: 50,
  },
  toggleText: {
    color: 'white',
  }
});

When the interval is triggered and the component is re-rendered that error will occur.

Matrix transform support

Hey,
is there any way to use animated values from this lib inside matrix transformation?
I have few animations where I had to change transform origin and since it's not supported in react native, matrix was the least hacky way to do that, unfortunately I'm getting cryptic error:

screenshot 2018-09-03 at 17 48 21

Basic sample:

import A from 'react-native-reanimated';

const deg = new A.Value(23);
const rad = A.multiply(A.divide(Math.PI, 180), deg);
const cos = A.cos(rad);
const sin = A.sin(rad);
const zAxisRotation = [
    cos, -sin, 0, 0,
    sin, cos, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1,
];
const Sample = () => {
    return (
        <A.View
            style={{
                transform: [{
                    matrix: zAxisRotation,
                }]
            }}
        />
    );
};

Can I animate the opacity of a shadow?

In the readme it states one of the goals as being

No more โ€œuseNativeDriverโ€ โ€“ all animations run on the UI thread by default

Could I animate the opacity of a shadow or the related shadow properties? What style props are native animations limited with this lib?

Interpolate functionality. [feature request]

Could look like this:

interpolate(
    nodeOrValue,
    {
        inputRange: [nodeOrValue, ...],
        outputRange: [nodeOrValue, ...],
    }
)

Questions:

  • Can this be implemented using existing node types?
  • Can the input range actually be animated?
    • If so how do we know when to stop searching for the closest values to the input value?
    • We could just take the first value that's greater than the input value.
    • Assuming the input range always increases even if animated then it will be stable.
  • How does the input range map to the output range?
    • Do we just force the arrays to be the same length and then map between them by index? This is how Animated does it.

I think a basic interpolate (interpolate(x, x0, x1, y0, y1)) could be made using existing node types.

I took a shot at implementing something using nested conds, it didn't go that well. I'll try again though, maybe with a different approach.

[Question] On the Interactable.View implementation

I was checking the Interactable.View implementation in reanimated (great job btw!). I noticed that you don't use spring anywhere. I would be interested to know how you manage the snap effect without it?

Thank you for your great work ๐Ÿ™‹๐Ÿผโ€โ™‚๏ธ

Release of .alpha-6

Would you guys be able to make a new alpha release?

diffClamp node is broken in the current one.

Also, I am not aware of the process but, how long it would take for that version to land in Expo?

The reason I ask is because I'll be imparting a workshop about animations and gestures with RN on a conference soon (12 September) and I was planning to showcase this library at the end, specially diffClamp for a collapsible navigation bar :)

It would be great to stick to Expo for all the examples and not having to resort to native compilation.

Let me know what you think.

Cheers!

Animated.timing does not execute the animation, whereas Animated.spring does

First of all, congratulations for this library. I am super excited about the value this will bring to the community to achieve gestures/interactions at 60 FPS on the main thread, in a declarative and composable way. Keep it going! ๐Ÿ’ช

I've been tinkering with it during the last to days and I've come across an issue with the timing node. I am using a simple animation when the component mounts to animate some navigation bar on the x-axis using transformX. With timing, what it happens is that the animation does not occur, the view just goes to the final value after the duration abruptly.

I've compared it to the spring node with a similar setup and the animation works as expected.

I am attaching the snippet I've used for that experiment. Maybe I am missing something on the timing configuration, or you'd lean towards some implementation flaw?

Thank you in advance!

Version of dependencies:

"react": "16.4.1",
"react-native": "0.56.0",
"react-native-reanimated": "1.0.0-alpha.5",

Example:

import * as React from 'react';
import { View, StyleSheet, Text, Easing } from 'react-native';
import Animated from 'react-native-reanimated';

const {
  Value,
  cond,
  set,
  startClock,
  clockRunning,
  stopClock,
  Clock,
  timing,
  spring,
} = Animated;

const NAV_BAR_HEIGHT = 56;

function runTiming(clock, value, dest) {
  const state = {
    finished: new Value(0),
    position: new Value(0),
    time: new Value(0),
    frameTime: new Value(0),
  };

  const config = {
    duration: 3000,
    toValue: new Value(0),
    easing: Easing.inOut(Easing.ease),
  };

  return [
    cond(clockRunning(clock), 0, [
      // If the clock isn't running we reset all the animation params and start the clock
      set(state.finished, 0),
      set(state.time, 0),
      set(state.position, value),
      set(state.frameTime, 0),
      set(config.toValue, dest),
      startClock(clock),
    ]),
    // we run the step here that is going to update position
    timing(clock, state, config),
    // if the animation is over we stop the clock
    cond(state.finished, stopClock(clock)),
    // we made the block return the updated position
    state.position,
  ];
}

function runSpring(clock, value, velocity, dest) {
  const state = {
    finished: new Value(0),
    velocity: new Value(0),
    position: new Value(0),
    time: new Value(0),
  };

  const config = {
    damping: 12,
    mass: 1,
    stiffness: 50,
    overshootClamping: true,
    restSpeedThreshold: 0.001,
    restDisplacementThreshold: 0.001,
    toValue: new Value(0),
  };

  return [
    cond(clockRunning(clock), 0, [
      set(state.finished, 0),
      set(state.velocity, velocity),
      set(state.position, value),
      set(config.toValue, dest),
      startClock(clock),
    ]),
    // we run the step here that is going to update position
    spring(clock, state, config),
    // if the animation is over we stop the clock
    cond(state.finished, stopClock(clock)),
    // we made the block return the updated position
    state.position,
  ];
}

class Example extends React.Component {
  componentWillMount() {
    this.transX = new Value(0);
    // Clock
    const clock = new Clock();
    // Timing does not work, there is no animation, just an abrupt change to the end frame.
    // this.transXAnimated = set(this.transX, runTiming(clock, 0, 300));
    this.transXAnimated = set(
      this.transX,
      runSpring(clock, this.transX, 0, 300),
    );
  }

  render() {
    return (
      <View style={styles.container}>
        <Animated.View
          style={[
            styles.navBar,
            {
              transform: [
                {
                  translateX: this.transXAnimated,
                },
              ],
            },
          ]}
        >
          <Text style={[styles.navBarTitle]}>
            Navigation Bar
          </Text>
        </Animated.View>
      </View>
    );
  }
}

export default Example;

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  navBar: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#C2185B',
    borderBottomColor: '#dedede',
    borderBottomWidth: 1,
    height: NAV_BAR_HEIGHT,
    zIndex: 2,
  },
  navBarTitle: {
    color: 'white',
    fontSize: 20,
  },
});

[Question] on Reanimated declaration

I've built an animation with reanimated that works great:


function runSpring(clock, value, dest) {
  const state = {
    finished: new Value(0),
    velocity: new Value(0),
    position: new Value(0),
    time: new Value(0),
  };

  const config = {
    damping: 20,
    mass: 1,
    stiffness: 100,
    overshootClamping: false,
    restSpeedThreshold: 0.001,
    restDisplacementThreshold: 0.001,
    toValue: new Value(0),
  };

  return [
    cond(clockRunning(clock), 0, [
      set(state.finished, 0),
      set(state.velocity, 0),
      set(state.position, value),
      set(config.toValue, dest),
      startClock(clock),
    ]),
    spring(clock, state, config),
    cond(state.finished, stopClock(clock)),
    state.position,
  ];
}

    this.translateY = cond(
      eq(gestureState, State.END),
      [
        set(translationY, runSpring(clockY, translationY, 0)),
        translationY,
      ],
      translationY,
    );

Where translationX comes from an event() handler. Why can't I write:

    this.translateY = cond(
      eq(gestureState, State.END),
      runSpring(clockY, translationY, 0),
      translationY,
    );

The second code snippet doesn't produce the excepted behavior. I'm still quite new with this library.

Calculate left/right window margins of zoomed in area

Hi there,

I am new to React and got here via Expo release notes. This isn't a bug but just trying to understand the code.

I'm trying to follow the Image example as I have a similar need (map).

I am trying to calculate the endpoints of the window as they end up after the transformations.

For example, for the sample image, if I zoom 2x with center of image, and move right by WIDTH/4, my corners will be (B, edge, I, edge). I would like to calculate those corners so I can request the right things from the server.

I am unable to follow the math here. Is this based on a simper example somewhere else? Or is there a trick for using the transformation matrix to get those corners?

Thanks,

simulator screen shot - iphone 6 - 2018-08-07 at 02 25 44

imageViewer example panning not scaled on iOS

I tried out the imageViewer example and when you zoom in on iOS, the panning translation does not scale with the zoom. So when zoomed in and panning, the image will move slower than the touch.

On android this worked correctly.

Causes problems with nested pan handlers on android

If you test this snack using reanimated on android you will see that when you try to pan the red box (parent), then it will not pan, however the child circle will pan. After tapping the parent box again the parent box will jump to the position of the drag distance of the blue circle even though the parent was not panned. According to react-native-gesture-handler docs they should be acting independently as one handler should steal control from the other. This works correctly on iOS.

To test if it was a problem with react-native-gesture-handler I made another snack that uses vanilla RN Animated with native driver and that works correctly on both platforms.

`createAnimatedComponent` does not support stateless functional components; use a class component instead.

Description

I just started a react native project to play around using react-native init and did the linking step.
Changed the default buildToolsVersion of my project from 23.0.1 to 25.0.0, which is the minimum sdk version required.
Only added this line of code to the default react-native project generated:

import Animated from 'react-native-reanimated;

And I get this strange error:

`createAnimatedComponent` does not support stateless functional components; use a class component instead.

I guess this could be related to this cc4ab7f ?

Steps to reproduce:

  • react-native init PlaygroundApp
  • yarn add react-native-reanimated
  • react-native link react-native-reanimated

Versions:

"react": "16.4.1",
"react-native": "0.56.0",
"react-native-reanimated": "^1.0.0-alpha.4"

Invalid prop "onHandlerStateChange" of type object

When I try out some examples I always get an error when using the iOS simulator and Expo 28.0.0 that says that onHandlerStateChange has an invalid prop. This happens when I copy the code from this example and also when I watch another tutorial one can clearly see the error in the simulator. Is this normal? Because Im really eager to learn reanimated, but when the examples dont work Im not exactly sure if there is something Im doing wrong or if the examples are wrong.

14:08:27: Warning: Failed prop type: Invalid prop onHandlerStateChange of type object supplied to Handler, expected function.

  • node_modules/prop-types/checkPropTypes.js:19:20 in printWarning
  • node_modules/prop-types/checkPropTypes.js:83:12 in checkPropTypes
  • node_modules/react/cjs/react.development.js:1228:19 in validatePropTypes
  • node_modules/react/cjs/react.development.js:1316:22 in createElementWithValidation
  • App.js:76:8 in render
  • node_modules/react-native/Libraries/Renderer/ReactNativeRenderer-dev.js:8811:23 in finishClassComponent
  • node_modules/react-native/Libraries/Renderer/ReactNativeRenderer-dev.js:12924:25 in performUnitOfWork
  • ... 16 more stack frames from framework internals

Listener in Animated.event

          onScroll={event(
            [
              {
                nativeEvent: {
                  contentOffset: {
                    y: this.scrollY
                  }
                }
              }
            ],
            {
              listener: () => {
                console.log('scrolling');
              }
            }
          )}

As in original Animated library, how do I pass a listener like this?

Array conditional for cond undocumented

I see the following in the example for imageViewer:

cond([delta, gestureActive],
   ...
)

I'm not sure what the behavior for an array conditional for cond is.

set location of a view with panGestureHandler

i try to create a seekbar with reanimated and panGestureHandler
i use of example folder to create draggable seekbar and thats work fine
but i want when user tap on somewhere of bar the toggle jump to where user tapped
plz help

my code:
`this.offsetX = new Value(0)
this.gestureState = new Value(-1)
this.onGestureEvent = event([
{
nativeEvent: {
translationX: this.dragX,
state: this.gestureState,
},
},
])
this.addX = add(this.offsetX, this.dragX)

this.transX = cond(
  and(eq(this.gestureState, State.BEGAN), eq(this.draging, 0)),
  [call([this.posX], this.startDraging)],
  cond(
    eq(this.gestureState, State.ACTIVE),
    [call([this.addX], this.setTime), set(this.draging, 1), this.addX],
    cond(
      and(
        or(
          eq(this.gestureState, State.END),
          eq(this.gestureState, State.CANCELLED),
          eq(this.gestureState, State.FAILED),
        ),
        eq(this.draging, 1),
      ),
      [
        block([
          set(this.offsetX, this.addX),
          set(this.currentTime, this.addX),
          call([this.addX], this.setVideoTime),
          set(this.draging, 0),
        ]),
      ],
    ),
  ),
)

<PanGestureHandler
maxPointers={1}
hitSlop={{
top: 15,
left: 15,
bottom: 15,
right: 15,
}}
onGestureEvent={this.onGestureEvent}
onHandlerStateChange={this.onGestureEvent}
>
<Animated.View
style={[
{
width,
height: 12,
flexDirection: 'row',
position: 'absolute',
alignItems: 'center',
bottom: 0,
left: -width,
},
{
transform: [
{
translateX: Animated.interpolate(
cond(greaterThan(this.draging, 0.5), this.transX, this.currentTime),
{
inputRange: [-1, 0, width, width + 1],
outputRange: [12, 12, width, width],
},
),
},
],
},
]}
/>

`

2nd time animation don't work well

I'm using react-native 0.57.2 and react-native-reanimated 1.0.0-alpha.9. I'm new with reanimated, so maybe I don't understand well, but I think I find a weird case. When mounting 2nd time a component with an animation, sometimes the animation don't work or start at a random place.

I reproduce using the rotation example :

import React, { Component } from 'react';
import { StyleSheet, Text, View, Alert, TouchableOpacity } from 'react-native';

import Animated, { Easing } from 'react-native-reanimated';

const {
  set,
  cond,
  startClock,
  stopClock,
  clockRunning,
  block,
  timing,
  debug,
  Value,
  Clock,
  divide,
  concat,
} = Animated;

function runTiming(clock, value, dest) {
  const state = {
    finished: new Value(0),
    position: new Value(0),
    time: new Value(0),
    frameTime: new Value(0),
  };

  const config = {
    duration: 5000,
    toValue: new Value(0),
    easing: Easing.inOut(Easing.ease),
  };

  return block([
    cond(clockRunning(clock), debug('clockRunning', clock), debug('clockNOTRunning', clock)),
    cond(clockRunning(clock), 0, [
      set(state.finished, 0),
      set(state.time, 0),
      set(state.position, value),
      set(state.frameTime, 0),
      set(config.toValue, dest),
      startClock(clock),
    ]),
    timing(clock, state, config),
    cond(state.finished, debug('stop clock', stopClock(clock))),
    state.position,
  ]);
}

class Screen1 extends Component {
  render() {
    return (
      <View
        style={[
          styles.box,
          { backgroundColor: 'blue' },
        ]}
      />
    );
  }
}

class Screen2 extends Component {
  trans = runTiming(new Clock(), 0, 360);

  render() {
    return (
      <Animated.View
        style={[
          styles.box,
          { transform: [{ rotate: concat(this.trans, 'deg') }] },
        ]}
      />
    );
  }
}

export default class Example extends Component {

  state = {
    screen: 'screen1',
  };

  handleClickScreen1 = () => {
    this.setState({screen: 'screen1'})
  };

  handleClickScreen2 = () => {
    this.setState({screen: 'screen2'})
  };

  render() {
    return (
      <View style={styles.container}>
        {this.state.screen === "screen1" ? (
          <Screen1 />
        ) : (
          <Screen2 />
        )}
        <TouchableOpacity onPress={this.handleClickScreen1} style={styles.button}><Text>SCREEN 1</Text></TouchableOpacity>
        <TouchableOpacity onPress={this.handleClickScreen2} style={styles.button}><Text>SCREEN 2</Text></TouchableOpacity>
      </View>
    );
  }
}

const BOX_SIZE = 100;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  box: {
    width: BOX_SIZE,
    height: BOX_SIZE,
    borderColor: 'white',
    alignSelf: 'center',
    backgroundColor: 'pink',
    margin: BOX_SIZE / 2,
  },
  button: {
    paddingVertical: 6,
    paddingHorizontal: 12,
    marginVertical: 6,
  },
});

The only difference I found, is that the first debug display of the first animation clockNOTRunning 0 and for the others animations it display a clock number clockNOTRunning 988059745.5713011.
And sometimes, when there is no animation, all debug only display :

clockNOTRunning 988350127.1424431
clockRunning 988356431.1301451
stop clock 0

Is it possible to animate height?

When I attempt to animate the height of a View or Scrollview, I get various errors. Is it possible to animate a component's height or width?

Animated.Text color

I'd love to be wrong about this, but it appears that Animated.Text doesn't support color being an animated style.

Works, renders a white box:

<Animated.View style={{ backgroundColor: Animated.color(255, 255, 255), width: 10, height: 10 }} />`

Doesn't work, renders black text:

<Animated.Text style={{ color: Animated.color(255, 255, 255) }}>Hello!</Animated.Text>`

Spring animations are "slow" to end

Thank you so much for making this great module. I started to build some video tutorial on how to use it:

I've built a couple of animations using the runSpring function that we can find in the examples of the repo. You can find one here: https://snack.expo.io/@git/github.com/wcandillon/can-it-be-done-in-react-native:tinder-swiping (components/Profiles.js).
I have a condition on when the clock is stopped by the spring animation, this condition always evalutes much later (few seconds) after the animation is seemingly done. Is that a behavior that sound famillar or I would need to provide a smaller example?

animated value nodes does not persist their state between reattach

Repro scenario:

  1. create animated.value initialized to 0
  2. use the above value on a component you can mount and unmount at will
  3. when component is mounted set value to something other than 0
  4. cause component unmount and mount so that the native part of the node gets recreated
  5. as a result when the value recreates it will be reset to the initial value

Cloning Repo and Building Fails: React/RCTEventEmitter.h file not found

Repo clone, yarn install, and react-native run-ios results in error:

react-native-gesture-handler/ios/RNGestureHandlerModule.h:1:9: fatal error: 'React/RCTEventEmitter.h' file not found

The file exists:

$ find . -name RCTEventEmitter.h
./node_modules/react-native/React/Modules/RCTEventEmitter.h

Animation control, Clock reset

Versions
"react": "16.6.1",
"react-native": "0.57.5",
"react-native-reanimated": "^1.0.0-alpha.10",

I want to be able to run and stop animations, while being able to listen to touches. Basically it's the progress indicator in audio player, so if audio is playing, animation is playing, if user drags the indicator, animation stops and I respond to gestures.

But I am lost with just simple running / stopping the animation.
This is the current behavior, the box jumps by value like it would move if clock was running all the time.
animationlag

I think it's because of the Clock? Below are two different versions
In the first one, I create one instance of clock and "control" that.
In the second one, I create new instance of the clock every time the runTiming() function is called, still I can stop it without any reference by stopClock(new Clock()).
How does this work? What am I missing? I so confused.

// @flow

import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import Animated, { Easing } from 'react-native-reanimated';
import React, { Component } from 'react';

const {
	Value,
	cond,
	clockRunning,
	startClock,
	set,
	timing,
	debug,
	stopClock,
	block,
	Clock,
	eq,
	call,
} = Animated;

function runTiming(clock, value, dest) {
// clock = new Clock();
	const state = {
		finished: new Value(0),
		position: new Value(0),
		time: new Value(0),
		frameTime: new Value(0),
	};

	const config = {
		duration: 3000,
		toValue: new Value(0),
		easing: Easing.linear,
	};

	return block([
		cond(clockRunning(clock), 0, [
			set(state.finished, 0),
			set(state.time, 0),
			set(state.position, value),
			set(state.frameTime, 0),
			set(config.toValue, dest),
			startClock(clock),
		]),
		timing(clock, state, config),
		cond(state.finished, debug('stop clock', stopClock(clock))),
		set(value, state.position),
	]);
}

const PLAYER_STATE = {
	PAUSED: 0,
	PLAYING: 1,
};

class SimplePlayer extends Component<{}> {
	clock: Clock;
	trans: Value;
	playingState: Value;

	constructor() {
		super();
		this.clock = new Clock();
		this.trans = new Value(0);
		this.playingState = new Value(PLAYER_STATE.PAUSED);
	}

	render() {
		return (
			<View style={styles.container}>
				<Animated.Code>
					{() =>
						block([
							cond(eq(this.playingState, PLAYER_STATE.PLAYING), [
								runTiming(this.clock, this.trans, 360),
							]),
							cond(eq(this.playingState, PLAYER_STATE.PAUSED), [
								stopClock(this.clock),
							]),
							cond(eq(this.trans, 360), set(this.trans, 0)),
						])
					}
				</Animated.Code>
				<Animated.View
					style={[styles.box, { transform: [{ translateY: this.trans }] }]}
				/>
				<TouchableOpacity
					onPress={() => {
						this.playingState.setValue(PLAYER_STATE.PLAYING);
					}}
				>
					<Text>RUN ANIM</Text>
				</TouchableOpacity>
				<TouchableOpacity
					onPress={() => {
						this.playingState.setValue(PLAYER_STATE.PAUSED);
					}}
				>
					<Text>PAUSE ANIM</Text>
				</TouchableOpacity>
			</View>
		);
	}
}

const BOX_SIZE = 100;

const styles = StyleSheet.create({
	container: {
		flex: 1,
		justifyContent: 'center',
		alignItems: 'center',
		backgroundColor: '#F5FCFF',
	},
	box: {
		width: BOX_SIZE,
		height: BOX_SIZE,
		borderColor: '#F5FCFF',
		alignSelf: 'center',
		backgroundColor: 'plum',
		margin: BOX_SIZE / 2,
	},
});

second version (shortened)
still works like the previous

function runTiming(value, dest) {
	const clock = new Clock(); // new clock instance
	const state = {
		finished: new Value(0),
		position: new Value(0),
		time: new Value(0),
		frameTime: new Value(0),
	};

	const config = {
		duration: 3000,
		toValue: new Value(0),
		easing: Easing.linear,
	};

	return block([
		cond(clockRunning(clock), 0, [
			set(state.finished, 0),
			set(state.time, 0),
			set(state.position, value),
			set(state.frameTime, 0),
			set(config.toValue, dest),
			startClock(clock),
		]),
		timing(clock, state, config),
		cond(state.finished, debug('stop clock', stopClock(clock))),
		set(value, state.position),
	]);
}

const PLAYER_STATE = {
	PAUSED: 0,
	PLAYING: 1,
};

class SimplePlayer extends Component<{}> {
	trans: Value;
	playingState: Value;

	constructor() {
		super();
		// this.clock removed
		this.trans = new Value(0);
		this.playingState = new Value(PLAYER_STATE.PAUSED);
	}

	render() {
		return (
			<View style={styles.container}>
				<Animated.Code>
					{() =>
						block([
							cond(eq(this.playingState, PLAYER_STATE.PLAYING), [
								runTiming(this.trans, 360),
							]),
							cond(eq(this.playingState, PLAYER_STATE.PAUSED), [
								stopClock(new Clock()), // no reference to instance
							]),
							cond(eq(this.trans, 360), set(this.trans, 0)),
						])
					}
				</Animated.Code>
				<Animated.View
					style={[styles.box, { transform: [{ translateY: this.trans }] }]}
				/>
				<TouchableOpacity
					onPress={() => {
						this.playingState.setValue(PLAYER_STATE.PLAYING);
					}}
				>
					<Text>RUN ANIM</Text>
				</TouchableOpacity>
				<TouchableOpacity
					onPress={() => {
						this.playingState.setValue(PLAYER_STATE.PAUSED);
					}}
				>
					<Text>PAUSE ANIM</Text>
				</TouchableOpacity>
			</View>
		);
	}
}

Not smooth animation

I have been playing with reanimated with the help of this tutorial, but I still find it sometimes stutter. It's not that smooth I suppose. You can check out this snack and confirm. Could you tell me what could be wrong so that I can improve? Or is this performance valid?

Animate on callback

I am playing around with this package and I came with an issue that animations do not get started on callback.

I think I am doing this wrong entirely, but here's the idea of what I am trying to achieve and I am seeking for help or ideas how to solve this.

I have n number of points along y axis. I get them by measuring views with .measure function
provided by react-native. When my draggable box gets dragged to some dropzone I want it to snap
to the center of that dropzone.

code for my y translation

  this._transY = cond(
     eq(this.state, State.ACTIVE),
     [
       set(this.transY, addY),
       set(this.prevDragY, this.dragY),
       this.transY
     ],
     [
       cond(eq(this.state, State.END), call([addX, absY], this.onDrop)),
       set(this.prevDragY, 0),
       this.transY
     ]
   );

my onDrop callback

 onDrop([x, y]) {
    let id = null;
   // just identifying on which dropzone draggable was dropped
    for(let i = 0; i < this.props.dropzones.length; i++) {
      let item = this.props.dropzones[i];
      if( y < item.yPage+item.height && y > item.yPage) {
        id = i;
        break;
      }
    }

   if(id !== null) {
    console.log(this.props.dropzones[id]);
  // this if gets called
  // I identify my dropzone correctly and I have correct coordinates for it here
  // but this block never gets executed and my draggable never animates
    this._transY = block(
    [
      debug('active', this._transY), 
       //these sets might not be correct, please don't mind them
      set(this.transY, add(this.transY, sub(this.props.dropzones[id].yPage, add(this.prevDragY, this.dragY)))),
      set(this.prevDragY, add(this.transY, sub(this.props.dropzones[id].yPage, add(this.prevDragY, this.dragY)))),
      this.transY,
    ]);
   }
  }

Make debug node logs show up for expo users

Currently debug node logs only show up in ios console or adb logcat on Android. We should think of a solution that would make those logs available for people who use expo and does not run it from xcode

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.