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

Implement 'loop' mode #12

Closed
bd-arc opened this issue Dec 6, 2016 · 25 comments
Closed

Implement 'loop' mode #12

bd-arc opened this issue Dec 6, 2016 · 25 comments
Assignees
Labels

Comments

@bd-arc
Copy link
Contributor

bd-arc commented Dec 6, 2016

If autoplay is set to true, the carousel jumps from the last slide to the first one whereas it would be better to provide an infinite loop.

@kingctan
Copy link

Good implement for swiper function in react native. and i also hope this feature will be ok asap. ^_^
thanks a lot.

@ranjithnori
Copy link

ranjithnori commented May 4, 2017

Hey @Exilz @bd-arc, how do you plan to implement loop mode ?
This package is great! :D

@bd-arc
Copy link
Contributor Author

bd-arc commented May 4, 2017

Hey @ranjithnori, to be honest, this is pretty complicated. We've played with different approaches so far, but everything we've tried had a flaw. Still, we are not giving up since we really want to implement this feature.

If you are aware of any article or code example that might help us, do not hesitate to share it with us ;)

@ranjithnori
Copy link

@bd-arc Sure thing! 👍

@DerMth
Copy link

DerMth commented Jun 12, 2017

@bd-arc this repo has implemented Infinite loop with the same scale animation / multiple slider displayed : https://github.com/juangl/react-native-infinite-carousel.
No doc or proper example, however the code can maybe help you !
This is the only feature that prevent me from using your lib :(

EDIT: I worked on the infinite loop. I duplicated the content, add a onSnapToItem(totaIitemsCount - 1) callback, and inside use the snapToItem(itemCount - 1, animated = false) method. Seems working on iOS.

@bd-arc
Copy link
Contributor Author

bd-arc commented Jun 12, 2017

Hi @MathieuSemain,
Thanks for the info; react-native-infinite-carousel seems interesting. I'm going to dissect its source code in order to see how it could help improving our own plugin.

Regarding your test, would you mind sharing a bit more code so I can have a better understanding of what you did?

@DerMth
Copy link

DerMth commented Jun 13, 2017

Hi,
Here is my code :

<Carousel
    ref="carousel"
    ...
    firstItem={this.props.slides.length}
    onSnapToItem={slideIndex => this.snapToItem(slideIndex)}
>
    { slides }
    { slides }
    { slides }
</Carousel>

And the snapToItem method :

snapToItem = (index) => {
        if (index >= ((this.props.slides.length * 3) - 3)) {
            this.refs.carousel.snapToItem(index - this.props.slides.length, false);
        }
        else if (index < 3) {
            this.refs.carousel.snapToItem(index + this.props.slides.length, false);
        }
    };

@bd-arc
Copy link
Contributor Author

bd-arc commented Jun 16, 2017

Hi @MathieuSemain,

Thanks for sharing your code. I have to say that I see at least three issues with this approach:

  1. snapToItem is not necessarily fired when slide animation is finished (see Make sure that onSnapToItem is triggered AFTER scroll animation's completion #34 for more info). This would result in jumps and flickers, and not a great user experience overall.
  2. The peaking previous and next items would just "disappear" when the slider is re-positioned.
  3. Momentum will be killed when reaching edges.

Since we're considering implementing FlatList, I was rather thinking about cloning slides on both edges of the slider and handling their addition/removal dynamically. The really tricky part would be to handle indexes properly.

What are you thoughts about all that?

@GROL
Copy link

GROL commented Jul 17, 2017

Hi guys,
My short trick :

  • add to slides list additional first item from end and last item from start.
let _items = [];
_items.push(<Image key={'loopLast'} source={{uri: this.banners[this.banners.length-1].src}} />);
this.banners.map(item => {
    _items.push(<Image key={item.id} source={{uri: item.src}} />);
});
_items.push(<Image key={'loopFirst'} source={{uri: this.banners[0].src}} />);

return (
    <Carousel
        firstItem={1}
        onSnapToItem={(slideIndex) => this.onSlideChange(slideIndex)}
        ... >
        {_items}
    </Carousel>
)
  • manually scroll to "native item" when current item is first or last
    onSlideChange(slideIndex) {
        // Emulate 'infinity loop'
        let newIndex = slideIndex;
        switch (slideIndex) {
            case 0:
                newIndex = this.state.banners.length;
                break;

            case (this.state.banners.length + 1):
                newIndex = 1;
                break;
        }
        if (newIndex !== slideIndex) {
            this._carousel.snapToItem (newIndex, true);
        }
    }

Enjoy :)

@est7
Copy link

est7 commented Sep 8, 2017

please implement it.....

@6axter82
Copy link

Hello,
thanks a lot for this awesome lib. Wanted to ask if there any updates on this issue?

@bd-arc
Copy link
Contributor Author

bd-arc commented Sep 19, 2017

Hi @6axter82,

I've previously been working on it, but I did face some nasty issues and weren't able to dig deeper until... today :-)

It's easily the most wanted feature at this time, and I really want to implement it. My hope is to be able to do so before the end of the month (maybe sooner). Stay tuned!

@bd-arc
Copy link
Contributor Author

bd-arc commented Sep 20, 2017

Ok guys, I've got some great news: I've been working on the "infinite loop" mode and it's coming along nicely.

In fact, you can already use the loop branch and see for yourself:

"react-native-snap-carousel": "https://github.com/archriss/react-native-snap-carousel#32c3353"

You can find the description of the relevant props here.

Now I need you to provide me with some feedback so I can fine-tune it before the release! This is still 'work in progress' (mostly on Android), but we're almost there ;-)

⚠️ If you test the plugin on Android, make sure to disable "JS Dev Mode" or, even better, to use a production version on a real device.

react-native-snap-carousel infinite loop mode

@est7
Copy link

est7 commented Sep 24, 2017

"react-native-snap-carousel": "git://github.com/archriss/react-native-snap-carousel.git#loop"

@bitcoinvsalts
Copy link

when I add loop={true} to my carousel, I am getting this error: Error while updating 'src' of a view managed by: RCTImageView

any idea why?

@bd-arc
Copy link
Contributor Author

bd-arc commented Oct 2, 2017

At last, I've released this feature in version 3.3.0 🎉

@bd-arc bd-arc closed this as completed Oct 2, 2017
@bd-arc
Copy link
Contributor Author

bd-arc commented Oct 2, 2017

@jsappme I really don't know what is going on with your carousel. Can you open a new issue and share some code?

@6axter82
Copy link

6axter82 commented Oct 6, 2017

Hi, I have tested it on the simulator and it looks nice. I have a small jump though, when I scroll fast and reach the last item of 3-by-default-added cards than I don't see any after. One second after a small jump is seen on the simulator screen and further items are added.
I am using:

"react": "16.0.0-alpha.6",
"react-dom": "^16.0.0-alpha.6",
"react-native": "0.43.2",
"react-native-snap-carousel": "^3.2.1",

loop_example

Any suggestions?..

@bd-arc
Copy link
Contributor Author

bd-arc commented Oct 6, 2017

@6axter82 Make sure to take a look at the description of prop loopClonesPerSide. Also, when developing for Android, this note is a must-read.

Note that 0.43.x is the first version of React Native that introduced the FlatList component upon which the plugin is based. As such, it's full of issues that might affect your experience with the plugin. A good way to know if that applies to you is by testing your code with the provided example (currently based on RN 0.48.4).

Hope this helps!

@6axter82
Copy link

6axter82 commented Oct 12, 2017

@bd-arc Thanks, I did implement the loopClonesPerSide prop and it is better now. but still there is a jump seen after I come to the edge or close to it.
I have encountered another issue though. in the onSnapToItemI do the following:

const { app, project, } = this.props.navigation.state.params;
...
<Carousel
...
loop={true}
loopClonesPerSide={10}
onSnapToItem={(index) => {
    console.log('current index of the Card is ', index);
    if (app[index].project._id != project._id) {
        console.log('blah');
    }
    // later usage of app{index] is not possible
    // when scrolling fast into the left direction, this sets index to negative value
}}
/>

I have three Cards and do 10 clones per side in order to catch up on the gaps at the edges (my previous issue described a bit up in this ticket). I get the print outs of the indices, and when I scroll fast than I get negative index, which is wrong as I after want to check on app[index].
Is this a bug?

@6axter82
Copy link

6axter82 commented Oct 12, 2017

Chrom Console

@screen shot 2017-10-12 at 14 40 23

screen shot 2017-10-12 at 14 41 31

@6axter82
Copy link

As a work around maybe implement a new property for Carousel, which is move to next card at swipe and not further. Which is not a better solution as we want to scroll fast enough as we want and not go to the lets say 30's card one by one.

@6axter82
Copy link

6axter82 commented Oct 12, 2017

I tried to play with loopClonesPerSide setting it to 3 and 5.

Setting it to 3 with carousel of 3 cards does not break the app, as the indices of newly added cards on the left side do not exceed 2,1,0;

In case of loopClonesPerSide={5} scrolling fast to the left edge before the new cards are added makes the index set to -2, and scrolling to the last card on the right side sets the index to 4. which is out of scope of the cards array.

screen shot 2017-10-12 at 15 08 09

@bd-arc
Copy link
Contributor Author

bd-arc commented Oct 12, 2017

@6axter82 Thanks for the useful feedback! Would you mind creating a new issue with your 4 latest comments?

@6axter82
Copy link

Yes, here it is #183

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants