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