software-mansion / react-native-reanimated Goto Github PK
View Code? Open in Web Editor NEWReact Native's Animated library reimplemented
Home Page: https://docs.swmansion.com/react-native-reanimated/
License: MIT License
React Native's Animated library reimplemented
Home Page: https://docs.swmansion.com/react-native-reanimated/
License: MIT License
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?
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.
If the animation function is called with all three arguments, then config
never goes through the AnimationClass which provides default values if they are not available.
It seems like there should be a consistent sanitizer function for the config that works the same both ways.
I'm noticing that this is the only place where _offset
is mentioned, thus implying that it would always be undefined
.
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],
},
),
},
],
},
]}
/>
`
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:
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,
}]
}}
/>
);
};
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
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
.
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 🙋🏼♂️
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!
"react": "16.4.1",
"react-native": "0.56.0",
"react-native-reanimated": "1.0.0-alpha.5",
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,
},
});
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.
Subject.
onScroll={event(
[
{
nativeEvent: {
contentOffset: {
y: this.scrollY
}
}
}
],
{
listener: () => {
console.log('scrolling');
}
}
)}
As in original Animated library, how do I pass a listener like this?
the suspense is killing me!
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:
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.
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.
I've added a double tap gesture handler to mimic the iOS native photoviewer behaviour but I'm not sure how to update the scale in my doubletap function. Any pointers?
It would be a nice feature to add possibility to use onLayout
in declarative way with Animated.Event
and normal non-animated View
I'm new to React world and trying to play with this library. I'm having issues running this example.
I deleted the following line in
https://github.com/kmagiera/react-native-reanimated/blob/master/Example/package.json
"postinstall":
"rm -rf node_modules/react-native-reanimated/{.git,node_modules,Example}"
And tried to run this with npm start
after npm install
. But I can't get the examples to run.
What is the prescribed way?
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?
Error: Unable to resolve module @babel/runtime/helpers/interopRequireWildcard
from /Users/maggialejandro/Documents/Github/react-native-reanimated/src/Animated.js
: Module @babel/runtime/helpers/interopRequireWildcard
does not exist in the Haste module map
Could look like this:
interpolate(
nodeOrValue,
{
inputRange: [nodeOrValue, ...],
outputRange: [nodeOrValue, ...],
}
)
Questions:
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 cond
s, it didn't go that well. I'll try again though, maybe with a different approach.
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,
]);
}
}
... and I want to know if it is stable enough for making the same things that the original Animated API does.
If not, what I can do to help?
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 ?
"react": "16.4.1",
"react-native": "0.56.0",
"react-native-reanimated": "^1.0.0-alpha.4"
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>`
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.
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.
Reporting here to track the progress of this issue.
Looks like the culprit could be 8888b3c since the problem surfaces in alpha.7 but not alpha.8
cc @ericvicenti
It appears sometimes, and is connected with calling callback on getting value during detaching.
3bbf8a0#diff-1ea1099449a3d9c97e383160f5a623e2R194
This line is breaking.
Maybe it is an issue in RN. Is there ay reason, @kmagiera, you decided not to use callback in call
node?
In order to repro e.g. navigate to "Interpolate" in Example app and then press back button
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!
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.
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
how to run some Animated.timing() in same time with reanimated ?
Whether I debug remotely in Chrome or watch the console output of expo, I do not get any debug messages.
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
It would be nice if we allow interpolation to accept nodes as well as its input/output
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.
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>
);
}
}
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?
Changing state of component via this.setState({})
from call
node give an error
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?
I am trying to wrap my head around this api by recreating this demo. http://chenglou.github.io/react-motion/demos/demo1-chat-heads/
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):
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.
sometimes when an animation is running and user press back and component unmount this error happening
in com.swmansion.reanimated.NodesManager
Repro scenario:
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?
There appears to be related to this line of code, which calls detach sometimes on null nodeId's: https://github.com/kmagiera/react-native-reanimated/blob/f607cebcd4b5f84a0c2b0446288de164dba512a4/src/createAnimatedComponent.js#L153
An easy solution would be to also check for a nodeId, like this:
oldPropsAnimated && oldPropsAnimated.__nodeId && oldPropsAnimated.__detach();
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)?
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,
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.