The program is really simple. I took a string of words, split them up using char and took those individual characters/letter and put them in an array. Then I made an array for the y position of each letter. The program just checks the y position of each letter as it falls and overlays that information with the pixel array of the video. If the y position of the letter is on a pixel in the video that is darker than a set threshold, then the speed of the letter reverses (which basically results in the letters seemingly staying in place when in between a dark and a light pixel, or between the background and an object).
Github Repository: https://github.com/yvonnehidle/textrain
Original Blog Post @ Arealess: http://www.arealess.com/text-rain-version-1/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | ////////////////////////////////////////////////////////////////// // GLOBAL VARIABLES ////////////////////////////////////////////////////////////////// import processing.video.*; Capture video; // string array for poem String poem = "Fancy lines and dancing swirls have nothing on simplicitys curls"; char[]letters = new char[poem.length()]; // letter positioning final int max = letters.length; float[]letterY = new float[max]; ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// // BASIC SETUP ////////////////////////////////////////////////////////////////// void setup() { // general setup size(640,480); noStroke(); textSize(20); fill(255,0,0); // video video = new Capture(this,640,480,30); // divide poem into individual characters for(int i=0; i<poem.length(); i++) { letters[i] = poem.charAt(i); } } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// // TABLE OF CONTENTS ////////////////////////////////////////////////////////////////// void draw() { background(255); // falling letters fallingLetters(); } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// // FALLING LETTERS ////////////////////////////////////////////////////////////////// void fallingLetters() { // if a webcam is available, load the video if(video.available()) { video.read(); } video.filter(GRAY); image(video, 0, 0); // variables float letterS=1; float letterX=0; float letterXSpace=width/letters.length; int darknessThreshold = 180; // generate the letters and have them interact // pixel by pixel of the video video.loadPixels(); for(int i=0; i<letters.length; i++) { // what is the pixel number in the array? int loc = int( letterX + letterY[i] * video.width ); // draw letters text(letters[i],letterX,letterY[i]); letterX=letterX+letterXSpace; // if the letters reach the bottom of the screen, start them at top again if(letterY[i] >= video.height - 1) { letterY[i] = 0; } // if the brightness of the pixel is less than our darkness threshold // then do not move the letter else if(brightness(video.pixels[loc]) < darknessThreshold) { if(letterY[i] > 10) { letterY[i]-=letterS; } } // else always move the letter else { letterY[i]+=letterS; } } } ////////////////////////////////////////////////////////////////// |