hyochan / react-native-masonry-list

The Masonry List implementation which has similar implementation as the `FlatList` in React Native
MIT License
392 stars 55 forks source link

Add support for Reanimated #14

Open Stevemoretz opened 2 years ago

Stevemoretz commented 2 years ago

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like A clear and concise description of what you want to happen. I would like to use this with reanimated 2 library, but how? Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered. I don't know if onScroll can be both used the way you used and the way reanimated 2 scroll handler uses it, would you mind telling us if it is possible? Additional context Add any other context or screenshots about the feature request here. https://docs.swmansion.com/react-native-reanimated/docs/api/useAnimatedScrollHandler/

hyochan commented 2 years ago

@DevYuns How does this sound to you as a reanimated lover?

DevYuns commented 2 years ago

@hyochan Looks quite an interesting suggestion 😄. But if trying to apply reanimated v2, I think you should make a major change to the component. The ways they treat an event or animation are slightly different.

Furthermore, I think there is no any benefit. The good part of reanimated V2 is that they can handle animation in other context so that we can make a smooth animation even though JS Thread is busy. But masonryList doesn't have a heavy complicated animation.

Stevemoretz commented 2 years ago

@hyochan Looks quite an interesting suggestion 😄. But if trying to apply reanimated v2, I think you should make a major change to the component. The ways they treat an event or animation are slightly different.

Furthermore, I think there is no any benefit. The good part of reanimated V2 is that they can handle animation in other context so that we can make a smooth animation even though JS Thread is busy. But masonryList doesn't have a heavy complicated animation.

Sorry I didn't mention the point of it, this would let you animate other stuff based on the scroll position or velocity of the scrollview/flatlist, which gives possibility for example to create a beautiful header like what Google Chrome uses on its Android version which hides when you scroll down and shows itself when you scroll up but not with an animation yes right now it's probably possible to do this with an animation but you can not interpolate the values to create a precise transition.

Furthermore there are some advanced examples, which benefit from this for example you can create a skew effect when you scroll for the items and depending on the velocity the skew level can be changed.

There are some advanced examples described in YouTube series "can it be done in react native"

I should've mentioned the use cases before, my apologies.

But also it would make the current design a bit more performant, yes not a lot but it does but the main point was about the flexibility that it provides to animate and transition other components based on the events of this one.

hyochan commented 2 years ago

@Stevemoretz This is great to discuss! Can you share the actual demo link that you'd like to be supported for better clarification?

Stevemoretz commented 2 years ago

Sure I wanted to share my own demo at first but it seems too complicated for start. There's a basic example on the official documentation:

https://docs.swmansion.com/react-native-reanimated/docs/api/useAnimatedScrollHandler/

just use styles.box to style the box. and the can be a big component on the height so it can be scrolled.

Here simply the scroll position will be added to the translation y of the box causing it to move along with the scroll view's scroll position which would make it move across the screen, pretty simple example but it shows all the other complex possibilities.

Stevemoretz commented 2 years ago

@Stevemoretz This is great to discuss! Can you share the actual demo link that you'd like to be supported for better clarification?

Just remembered something extremely important, if you can change your component from a functional component to a class component, this probably even works out of the box.

Reanimated doesn't include flatlist by default but since flatlist is a class component, but using this function:

Animated.createAnimatedComponent

That can happen, I need sometime to modify yours to class component and see if it will work out of the box, I'll share the information here.

Stevemoretz commented 2 years ago

The tests I ran were pretty promising and I got it working :) In the meanwhile I realized that your component doesn't support refs right now, maybe I should put that in a separate topic but since I'm suggesting to change the component here this could be considered as an add-on.

First about the ref you know that FlatList ref is pretty useful I end up using it a lot to programmatically, scroll to a given index which is really useful in a lot of cases, so I'm suggesting maybe you could focus on that for the next version of your library.

Now in order to support reanimated 2 and all its phenomenal features, you're only one step away I wanted to do a PR but since I got to the point that refs should be supported and I don't know how FlatList does the programmatic scroll I gave it up, and that step is to convert your functional component to a class component.

This is how I tested it, first I wrapped your functional component with a class component.

class MasonryListClass extends React.Component<any> {
    render() {
        return <MasonryList {...this.props} />;
    }
}
export default MasonryListClass;

Now I make it an animatable component using this:

const MasonryListAnimated = Animated.createAnimatedComponent(MasonryListClass);

And now we can use it:

    const onScroll = useAnimatedScrollHandler({
        onScroll: ({contentOffset}, context) => {
            console.log(contentOffset.y);
        },
    });

    return (
        <MasonryListAnimated
            onScroll={onScroll}
            data={[1, 2, 3, 4, 5, 6]}
            numColumns={2}
            renderItem={({item, i}) => {
                return <SG.DebugView style={{marginTop: 50, height: i * 50}} />;
            }}
        />
    );

Now if you scroll you see in the console the position logging, but this is a log from UI thread not a regular log, Now we can create a header like google chrome and a lot more 💯 .

Thankfully I remembered about this function and didn't give you a headache by making you go after the way of making it happen in another direction but I really hope you consider the other thing about refs that'd be great to have those functionalities.

Stevemoretz commented 2 years ago

@Stevemoretz This is great to discuss! Can you share the actual demo link that you'd like to be supported for better clarification?

Just remembered about this and came back to check so did you ignore it because it was stupid, or you forgot about this? lol

hyochan commented 2 years ago

@Stevemoretz I am sorry there! I am having really busy days until Oct 17th 😢 .

I might have to come back after that.

P.S. @DevYuns <==== he has more time.

Stevemoretz commented 2 years ago

@Stevemoretz I am sorry there! I am having really busy days until Oct 17th 😢 .

I might have to come back after that.

P.S. @DevYuns <==== he has more time.

Thank you for the response, that's totally fine I'm not in a hurry either, just was asking to see why you never answered back, and if you thought this was a bad idea but looks like you've been busy, so good luck with what you're doing, let's get back to this whenever you would have some free time.

hyochan commented 2 years ago

@Stevemoretz I am here to share the request you've suggested. I'm not currently sure how to support the Animated component on a custom React Component. Therefore, I've had to create a new one here reanimated-masonry-list.

Would you want to try this out and see if this fits your needs?

Stevemoretz commented 2 years ago

Hi, thank you that sounds amazing!

qaws5503 commented 1 year ago

Is this solved? I can't use onScroll neither reanimated-masonry-list nor Animated.createAnimatedComponent.

suggoooiii commented 1 year ago

Hello

alexkompaniets-rio commented 1 year ago

Doesn't work for me too