question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Animated.View does not change position called with timing until I do not force rerender.

See original GitHub issue

Hi, I have been struggling with some problem.

I have an idea of taking “block” and drag it to other place, but with possibility to undo this action and revert the action (confirmed on modal). Unfortunately block does not move until I force change on transform prop by changing state of some value.

Code for calling undo action

undoDragging = () => {
        // This forces re-render and not denies queued animations.
        this.setState(
            ({ verticalScrollOffset }) => ({
                animating: true,
                verticalScrollOffset: verticalScrollOffset ? 0 : 1,
            }),
            () => {
                timing(this.Y, timingAnimationConfig(500, 0)).start();
                timing(this.X, timingAnimationConfig(500, 0)).start();
            },
        );
    };
<Animated.View
    style={[
        {
            transform: [
                { translateY: verticalScrollOffset },
                { translateY: this.Y },
                { translateX: this.X },
            ],
        },
    ]}
>

Unless I do not call this setState for changing verticalScrollOffset Block will never move.

Another problem is that block sometimes is going back in one direction or another 😄 and it’s really annoying 😄

GIF

ezgif com-video-to-gif

P.S. Without changing verticalScrollOffset on setState block will never move. Of course moving block is implemented in PanGestureHandler

        this.panHandler = event([
            {
                nativeEvent: ({ translationX: x, translationY: y, state, absoluteX, absoluteY }) =>
                    animationBlock([
                        condition(eq(state, GestureState.ACTIVE), [
                            set(this.X, multiply(round(divide(add(x, this.offsetX), columnWidth)), columnWidth)),
                            set(this.Y, add(y, this.offsetY)),
                        ]),
                    ]),
            },
        ]);

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:4
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

5reactions
osdnkcommented, Dec 11, 2018

@dsznajder I’va handled to fix your case. I’m extremely thankful to you since your issue have realised me that maybe not everything in reanimated is very clear and understandable.

So firstly let you see the code: https://gist.github.com/osdnk/4a5b3d2237c4c4558c8d3280a50eb118

Maybe not everything is clear so I hasten to explain:

The first problem is this.panHandler function. To understand it properly please realised it’s not a real function but set of animated values which are being updating. So if you call this method only onGestureEvent the state will always be active. Why is it a problem? If we update something in block which is result of the function, the whole block is being reevaluated and it might provide to unwanted effects (e.g. your timing animation was probably working withouts forcing update, but it was immediately overriding by setters from onGestureEvent 😅 ). So I merged onHandlerStateChange with onGestureEvent and it appears to work.

2reactions
chillios-tscommented, Dec 11, 2018

@osdnk Here you have snack demo: https://snack.expo.io/ByfLIepJ4

If you first setState here:

undoDragging = () => {
        // This forces rerender and not denies queued animations.
        this.setState(
            ({ verticalScrollOffset }) => ({ animating: true, verticalScrollOffset: verticalScrollOffset ? 0 : 1 }),
            () => {
                timing(this.opacity, timingAnimationConfig(250, 1)).start();
                timing(this.Y, timingAnimationConfig(300, 0)).start(() => {
                    setTimeout(() => {
                        this.blockContainer.setNativeProps({ style: { borderLeftColor: "green" } });
                        this.setState({ animating: false });
                    }, 300);
                });
                timing(this.X, timingAnimationConfig(300, 0)).start();
            },
        );
    };

The block stops animating back 😃 I hope this helps.

P.S. Android and iOS works differently, sometimes iOS works but Android don’t.

Read more comments on GitHub >

github_iconTop Results From Across the Web

React native animation.reset doesn't reset the animation
Try calling .start() after .reset() . That replays the animation. If you call .start() after it finishes playing without resetting, ...
Read more >
Animations | React Native Reanimated - Software Mansion
In case you'd like to wait with the next animation until the previous one is finished, or in the case you'd like to...
Read more >
How Animations Work in React Native - freeCodeCamp
The animation starts. JavaScript runs the requestAnimationFrame function - a function which tries to run at 60 calls/second (60 FPS) JavaScript ...
Read more >
CSS Animations tips and tricks - MDN Web Docs
The animation details are included in the "changing" class, which says that the @keyframes named "colorchange" should be used over the course of ......
Read more >
Performance Overview - React Native
Profile your performance and memory usage when using these props. If you don't plan to move a view anymore, turn this property off....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found