Number Zoom


  // Number Zoom - Continuous cross-fading zoom effect by Jim Bumgardner (joyofprocessing.com)
  
  PImage tex;
  
  float  duration = 5*1000;
  
  float scalarWrap(float v) // Wrap texture coordinates that exceed 0-1 range in either direction.
  {
    if (v < 0) {
      v = -v;
      v = 1-(v-(int) v);
    } else {
      v -= (int) v;
    }
    return v;
  }
  
  void setup()
  {
    /* @pjs preload="/1010.png"; */
  
    size(500, 500);
    // size(600,600, OPENGL);     // Use OPENGL if you can...
    // hint(ENABLE_OPENGL_4X_SMOOTH);
    // hint(DISABLE_OPENGL_ERROR_REPORT);
    
    smooth();
    tex = loadImage("/1010.png");
    tex.loadPixels();
  }
  
  void draw()
  {
    background(255);
    noStroke();
  
    loadPixels();
    float r = millis()/duration;
    r -= (int) r;
  
    float r2 = (millis()+duration/2)/duration;
    r2 -= (int) r2;
    
    float startWidth = 1;                               // Beginning width of first layer in texture-space
    float endWidth = tex.width;                         // Ending width of first layer in texture-space
    float z = endWidth/startWidth;                      // Zoom ratio
  
    int fullImage = width*height;
  
    float curWidth = startWidth*pow(z, r);              // Determine current width in texture-space (0-1)
  
    PImage t1 = tex;
    
    PImage t2 = tex;
  
    for (int i = fullImage-1; i >= 0; --i) {
      int px = (i % width) - (width/2);                 // Pixel Coordinates, offset so we zoom from center
      int py = (i / width) - (height/2);
  
      float px1 = px*curWidth/width;                    // Texture Coordinates (0-1 across texture)
      float py1 = py*curWidth/width;
  
      float fx1 = scalarWrap(px1);                      // Wrapped Texture Coordinates
      float fy1 = scalarWrap(py1);
  
      int dx1 = (int) (fx1*t1.width) % t1.width;        // Texture pixel coordinates
      int dy1 = (int) (fy1*t1.height) % t1.height;
  
      float v1 = t1.pixels[dy1*t1.width + dx1] & 0x0FF; // Texture color at this location
  
  
      float fx2 = scalarWrap((.5 + px1/t2.width));      // Wrapped Texture Coords for second layer
      float fy2 = scalarWrap((.5 + py1/t2.width));
      int dx2 = (int) (fx2*t2.width) % t2.width;        // Texture Pixel Coords for second layer
      int dy2 = (int) (fy2*t2.height) % t2.height;
  
      float v2 = t2.pixels[dy2*t2.width + dx2] & 0x0FF; // Texture color at this location
  
      float ra = r*r*(3-2*r);                           // Alpha cross-fade with Ease In/Out
  
      int v = (int) ((v2 * ra) + (v1 * (1-ra)));        // Tween between color values
  
      pixels[i] = v | (v << 8) | (v << 16) | 0xFF000000; // Set pixel value
    }
  
    updatePixels();
  }
  // DONE