What should I do if I want to show thousands of pages in a slide-box

I am quite curious about how you make the circular-buffer with the animation(slide-in-left/right).
Would you please share the main code with me? :slight_smile:

Nothing special in the code. Here are some relevant bits. I realize there are more efficient ways to code this but to me it’s more important that the code is easy to follow for all cases :wink:

<ion-view>
    <ion-slide-box does-continue="true" show-pager="false" on-slide-changed="slideChanged($index)">
        <ion-slide ng-repeat="single in data.singles track by $index">
            <ion-content>
                <div class="padding">
                         ....
                </div>
            </ion-content>
        </ion-slide>
    </ion-slide-box>
</ion-view>


app.config( function( $stateProvider, $urlRouterProvider ) {
   $stateProvider
...
      .state( 'app.single', {
         url: "/single/:index?newObject",
         views: {
            'tab-search': {
               templateUrl: "templates/single.html",
               controller: 'SingleCtrl'
            }
         }
      } )

.controller( 'SingleCtrl', ... {

      var countBostad;
      var curIndex = parseInt( $params.index );
      var lastIndex;
      var lastSlide;

      var loadSingles = function( index ) {
         var previndex = index - 1;
         var nextindex = index + 1;
         if( previndex < 0 ) previndex = countBostad - 1;
         if( nextindex >= countBostad ) nextindex = 0;
         $scope.data.singles[ 0 ] = $scope.data.bostad[ previndex ];
         $scope.data.singles[ 1 ] = $scope.data.bostad[ index ];
         $scope.data.singles[ 2 ] = $scope.data.bostad[ nextindex ];
         console.log( "loadSingles: " + previndex + " " + index + " " + nextindex + " of " + countBostad );
      }

      $scope.slideChanged = function( toSlide ) {
         if( toSlide == lastSlide ) return;
         console.log( " > slideChanged " + lastSlide + " > " + toSlide );
         var slideToLoad;
         var loadIndex;
         switch( lastSlide + ">" + toSlide ) {
            case "0>1":
            {
               slideToLoad = 2;
               curIndex = curIndex + 1;
               loadIndex = lastIndex + 2;
               break;
            }
            case "1>2":
            {
               slideToLoad = 0;
               curIndex = curIndex + 1;
               loadIndex = lastIndex + 2;
               break;
            }
            case "2>0":
            {
               slideToLoad = 1;
               curIndex = curIndex + 1;
               loadIndex = lastIndex + 2;
               break;
            }
            case "0>2":
            {
               slideToLoad = 1;
               curIndex = curIndex - 1;
               loadIndex = lastIndex - 2;
               break;
            }
            case "1>0":
            {
               slideToLoad = 2;
               curIndex = curIndex - 1;
               loadIndex = lastIndex - 2;
               break;
            }
            case "2>1":
            {
               slideToLoad = 0;
               curIndex = curIndex - 1;
               loadIndex = lastIndex - 2;
               break;
            }
         }

         if( curIndex < 0 ) curIndex = countBostad - 1;
         if( curIndex > countBostad ) curIndex = 0;

         if( loadIndex < 0 ) loadIndex = countBostad + loadIndex;
         if( loadIndex > countBostad ) loadIndex = loadIndex - countBostad;

         console.log( "   reload " + slideToLoad + " with " + loadIndex );

         $scope.data.singles[ slideToLoad ] = $scope.data.bostad[ loadIndex ];
         lastSlide = toSlide;
         lastIndex = curIndex;
      }

   } ] )

I cannot see much differences between the code and your last codepen example.
What is in your SingleCtrl to make the circular buffer?

Then you need to open your eyes, man!

The Codepen uses one slide per collection element and only renders three of them into the DOM.
So if you have 1000 elements you will have 997 empty slides and 3 populated slides in your DOM.

The code above uses a total of 3 slides ($scope.data.singles) independently of collection size, and keeps their content “centered” on the curIndex element, as if the three slides where connected in a triangle (=circular buffer).
So if you have 1000 elements you will still have only 3 slides in your DOM.

The loadSingles() function does the initial load of the 3 slides when the view is entered.
The slideChanged() function does the updating when the user slides, re-populating the slide that was “left behind” with the on that will be entered if the user continues to swipe in the same direction.

Got it. Thank you! :slight_smile:

You can try this too:

7 Likes

That is exactly what I want. Thanks a lot!

This is great @zarko. I am going to try and apply this to my usage now. Just curious, what does nr stand for?

nr for “number”. It’s basically a dynamically generated numeric value for every slide so that we know in which direction we are sliding / which slide content needs to be shown.

1 Like

@zarko I got it working! In my case I dont have an infinite amount of slides but its a large set and I still like your implementation as an optimization. Imagine this. I have 50 slides (and I have all the data for them on controller load). I jump in to the slidebox at 30 and load 29,30,31 as my defaults and then when it hits the make slide, i just find the appropriate data and load it in. Brilliant!

The only thing Im struggling with and trying to figure out is how to set some upper/lower limits. Mainly how to set does-continue to false when you hit a certain slide. For example, in your example, say you wanted the carousel to not scroll any further than -5 or +6.

UPDATE: So I was able to prevent scrolling by using $ionicSlideBoxDelegate.$getByHandle('slideshow-slidebox')._instances[0].loop(false); if im on the first or last slide but the trickier part is when you arrive at the slide it has to be the head (if its your lower bound) or the tail (if its your higher bound). This is more difficult than I anticipated.

good to hear you had some progress. perhaps i or anyone wanting can soon create the ultimate component / ion that does all this magic.

That would be the ultimate slider @zarko and solve a lot of performance issues for a lot of people. I’ll keep stabbing at it but I have kind of hit a brick wall at the moment. The fact that it has to end on the tail (or the lower limit has to end up as the head) has really stumped me.

Hi guys,

I’ve implemented a similar version of the circular buffer for the slider but I’m stuck at one point.
Basically I want to implement the circular slider but with a start and end, as in, it would prevent sliding from the first image of the array to the last image…

I’ve tried changing the does-continue to false when it reaches the last/first image of the gallery but it doesn’t seem to work (Even if triggering the update method of the delegate)

Any thoughts ?

Any progress here? @zarko @travisdahl
Im currently trying to achieve the exact same thing.

I have a certain amount of slides, lets say 100. I want to start at the first one and automatically fill the other two slides with the next ones out of these 100, so the user has the feeling of an endless scrolling. When it comes to slide 100, scrolling in the right direction should stop, only a backwards scrolling/sliding is then possible.

Same thing in the other direction, but if the user hits slide 0, no more scrolling in left direction should be possible…any help would be appreciated!

I would also be happy to find a solution :blush:

So I’m working on a dirty-as-hell solution to this, still expecting to gain significant performance boost compared to a dumb slidebox with all n slides in the DOM.

Basically I have n slides (0 to n-1). I generate slides 1 through n-2 in zarko’s circular buffer (3-slide) slidebox with does-continue=true.

I have two other slideboxes in the template for the head and tail (2 slides each, does-continue=false) that overlap with the main slidebox (slides 0 and 1, n-2 and n-1, respectively). Then I just ng-show and ng-if them on reaching the head/tail and voila…

Please let me know if someone has already come up with a cleaner solution!

I wonder if anyone came up with a good solution a year after the last post. The circular buffer technique works but doesn’t address the need of stopping the slide at the first and last slide.

Hi,

I have to show chart from today to (today - n days)
My “solution” based on zarko’s code :

Today : nr=0
today-1 : nr=-1
today-2 : nr=-2

I hide all content on the slide nr=1, slide stops with bounce.

$scope.slideChanged = function ( i ) {
    var
    previous_index = i === 0 ? 2 : i - 1,
            next_index     = i === 2 ? 0 : i + 1,
                    new_direction  = $scope.slides[ i ].nr > $scope.slides[ previous_index ].nr ? 1 : -1;
                    angular.copy(
                            createSlideData( new_direction, direction ),
                            $scope.slides[ new_direction > 0 ? next_index : previous_index ]
                    );
                   var lastTail = 0;
                if($scope.slides[i].nr==(lastTail+1)){
                    $ionicSlideBoxDelegate.$getByHandle('slideshow-slidebox').slide(getIfromNr(lastTail));
                }
}

var getIfromNr=function(nr){

        for (var i = 0; i < $scope.slides.length; i++) {
            if ($scope.slides[i].nr == nr) {
                return i;
            }
        }
    return -1;
}

Hi,
I don’t understand what you mean and don’t see where you’re hidding stuff in the code.
Could you please elaborate more ?
Are you happy with this solution so far ?

Thx

You can see my codepen

select first and last slide number

$scope.slideShow={ first:-3, last:2 };

I’m trying to do same with amazing ion-slides (ionic 1.2), but there’s maybe some issues.

1 Like