// 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