Infinite scrolling?!

Hey,

There are several ways you can approach this. I wrote something you can start playing with that could work as a proof of concept if you don’t need a lot of control and manipulation of the images.

I created an Img object that contains some information about how to position an image within a grid, how to update the x and y values, and update the index position with an array. The objects essentially get recycled as you scroll up or down. I don’t use the scroll wheel in my sketches so there is a bit of an issue when scrolling at high speeds and you try to recycle the Img objects. If you are doing this on a website it might be easier as you wouldn’t be placing the object based on it’s x and y precisely but below or above a

or some other tag. This would keep the spacing consistent, however, this is a start.

You will just need to update a path to a folder with images (used three images buy duplicated them several times). I sized all my images to 200 x 200 pixels. However, if there is no valid path to images or once you scroll beyond the available images you just get a rect with a random fill and a display for the index number showing it would be updating with the corresponding image should there be one available.

With this approach you are only loading a few images at a time which would work as a proof of concept depending on the size and number of images. Perhaps not the most efficient, but again, a start.

infinite_scroll_sm

/**************************************************************
 Project:  Infinite vertical scroll template with and w/o images
 
 Notes:
 - Processing 4.0b2
 - update path to folder containing images 
 
 To Do:
 - improve scroll element
 - improve scroll end (i am sure you'll need an end at some point
     or you can loop?)
 
 **************************************************************/
 
ArrayList<Img>   images;        // array list of Img objects
String[]         filenames;     // array of image file names (String)
String           path;          // path to folder containing images
boolean          pathValid;     // toggle if path to images contains images

void setup() {
  size(900, 900);
  
  // update path to folder containing your desired images
  // I downloaded some random images to and images folder
  // within my downloads folder
  path = "C:/Users/asher/Downloads/images";
  pathValid = false;
  
  // can use relative path to sketch folder
  //java.io.File folder = new java.io.File(sketchPath(""));
  
  // create list of image file names in desired folder
  java.io.File folder = new java.io.File(path);
  filenames = folder.list();
  // check to see if images were obtained via path
  if((filenames != null)) {
    pathValid = true;
    println(filenames.length, "images available:");
    for(int i = 0; i < filenames.length;i++) {
      println(filenames[i]);
    }  
  } 
  
  // initialize list of Img objects
  images = new ArrayList<Img>();
  
  // place Img objects in display grid of
  // 3 x 3 with a 4th row loaded but not visible
  for(int y = 0; y < 4; y++) {
    for(int x = 0; x < 3; x++) {
      images.add(new Img(x, y, 200));
    }
  }   
}

void draw() {
  background(240);
  
  // display img objects with desired images
  for(Img img: images) {
    img.display();
  }
  
  // create a basic banner
  noStroke();
  fill(220);
  rect(0, 0, width, 150);
  
  // display app name and/or other UI elements
  fill(0);
  textAlign(CENTER, CENTER);
  textSize(40);
  text("Infinite Scroll", width/2, 75);     
}

/** 
* scroll wheel function
*/
void mouseWheel(MouseEvent event) {
  // update Img objects position based on scroll
  float e = event.getCount();
  for(Img img: images) {
    img.update(e);
  }
}

/**
* Class that holds an image and controls its movement and postion
*/
class Img {
  float       x, y;              // the x and y position in pixels    
  int         xIndex, yIndex;    // the x and y position as index locations
  int         imgSize;           // the size of the image
  float       scrollSpeed;       // speed of scroll
  color       imgColor;          // default of image box (when no images being used)
  int         index;             // index position within filenames list
  int         startIndex;        // hold original index for position look up
  int         runningScroll;     // track scrolling
  PImage      img;               // the image itself
   
  /**
  * Constructor
  * @param {int} _x    x position of the image (index)
  * @param {int} _y    y position of the image (index)
  * @param {int} _s    image size
  */
  Img(int _x, int _y, int _s) {
    xIndex = _x;
    yIndex = _y;
    
    // get starting index
    index = xIndex + yIndex * 3;
    startIndex = index;
    
    // spacing for x and y position
    x = 125 + (xIndex * 225);    
    y = 200 + (yIndex * 225);
    imgSize = _s;
    
    scrollSpeed = 20;
    runningScroll = 0;
    imgColor = color(255, random(150, 225), random(255));
    
    // load image per index
    updateImage();
    
  }
  
  /**
  *  update the position per scroll wheel
  *
  * @param {float}  _y     the scroll value from wheel
  */
  void update(float _y) {
    
    // not the best logic for controlling scroll but a start
    // scroll up and down unless at initial itial photo in filenames
    // #TODO optimize this
    if(runningScroll < 0) {
      y += map(_y, -5, 5, -scrollSpeed, scrollSpeed);
      runningScroll += map(_y, -5, 5, -scrollSpeed, scrollSpeed);      
    } else {
      if(_y > 0) _y = 0;
      y += map(_y, -5, 0, -scrollSpeed, 0);
      runningScroll += map(_y, -5, 0, -scrollSpeed, 0);   
    }   
    
    // update y position with boutn checking
    // not the greatest but works as a start
    // recycle img by moving y position to bottom of canvas
    if(y < -25) {
      
      // for infinite scroll use this
      index += 12;
      updateImage();
      if(startIndex < 3) { 
        y = images.get(startIndex + 9).y + 200 + 25;
      } else {
        y = images.get(startIndex - 3).y + 200 + 25;
      }
      
      // #TODO: to limit scroll to images in folder uncomment this
      // and comment above code
      //index += 12;
      //if(index < filenames.length) {
      //  if(startIndex < 3) { 
      //  y = images.get(startIndex + 9).y + 200 + 25;
      //  } else {
      //    y = images.get(startIndex - 3).y + 200 + 25;
      //  }
      //  updateImage();
      //} else {
      //  index -= 12;
      //}
    }
    
    // recycle img by moving y to top of canvas
    if(y > 875) {
      index -= 12; 
       if(startIndex < 9) {       
        y = images.get(startIndex + 3).y -  200 - 25;
      } else {
        y = images.get(startIndex - 9 ).y - 200 - 25;
      }
      updateImage();     
    }  
  }
  
  /**
  *  method for updating image to be displayed
  */
  void updateImage() {
    
    if(pathValid) {
      if(index >= 0 && index < filenames.length) {
        img = loadImage(path + "/" + filenames[index]);
      }
    }
  }
    
  /**
  * display the image and appropriate position
  */
  void display() {
    // when no images used
    fill(imgColor);
    rect(x, y, imgSize, imgSize);
    
    // display index values of img
    fill(0);
    text(index, x + 100, y + 100);
       
    // display image if there is a valid path to images
    // and within number of images (otherwise it loops images)
    if(pathValid) {
      if(index < filenames.length) {
        image(img, x, y);
      }
    }   
  }  
}
2 Likes