Mar 092010
 

For today’s March Madness program I made a visualization of Tumblr quotes from a few friends I follow. I turn the text into a tumbleweed and let it ramble on by across the screen. It could definitely use some optimization as canvas doesn’t seem to handle lots of text rendering too well. Source is after the break.

JPLT.Class.create("JPLT.TextTumbleweed", JPLT.Object,
	function(str) {
		this.str = str;
		this.reset();
		this.createPhrases();
	},
	{
		reset: function() {
			this.active = false;
			this.x = -50 + Math.random() * -200;
			this.y = 267 + 133 * Math.random();
			this.baseY = this.y;
			this.speed = Math.random() * 5 + 1;
			this.r = Math.random() * Math.PI/8 - Math.PI/16;
			this.size = 10 + Math.random()*10;
			this.color = "rgb(" + Math.floor(Math.random()*50) + "," + 
				Math.floor(Math.random()*50) + "," + 
				Math.floor(Math.random()*50) + ")";
		},
		
		run: function() {
			if (this.active) {
				this.r += this.speed/5 * Math.PI/16;
				if (this.r > Math.PI*2) {
					this.r -= Math.PI*2;
				}
			
				this.x += this.speed;
				this.y = this.baseY + Math.abs(Math.cos(this.r)) * this.speed * 5;
				
				if (this.x > window.innerWidth + 200) {
					this.reset();
					this.fireEvent("weedInactive");
				}
			}
		},
		
		createPhrases: function() {
			var phrase;
			var words = this.str.split(/\s+/);
			
			this.phrases = [];
			
			while(words.length) {
				phrase = "";
				while(words.length && phrase.length < 25) {
					phrase = phrase + words.shift() + " ";
				}
				
				this.phrases.push({ 'phrase': phrase, 'random': Math.random() });
			}
		},
		
		paint: function(ctx) {
			try {
				if (this.active) {
					var random;
					var phrase;
					var r = this.r;
			
					ctx.save();
			
					ctx.fillStyle = this.color;
					ctx.translate(this.x,this.y);
			
					for (var i=0; i/,"").replace(/&#\d+;/,"");
		},
		
		excerptize: function(str) {
			if (str.length > this.quoteLength) {
				str = str.substr(0,this.quoteLength-3) + "...";
			}
			
			return str;
		},
		
		createTumbleweed: function(str) {
			var weed = new JPLT.TextTumbleweed(str);
			this.weeds.push(weed);
		},
		
		activateWeed: function() {
			var weed;
			
			for (var i=0; i<10; i++) {
				weed = this.weeds[Math.floor(Math.random() * this.weeds.length)];
				if (!weed.active) {
					this.log("Activating " + weed.str);
					weed.active = true;
					return;
				}
			}
			
			window.setTimeout(this.delegate(this.activateWeed), 5000);
		},
		
		loaded:function(data) {
			var posts = data.posts;
			for (var i=0; i