/** * Burning Words, * Effect of burning text with an ability to customize colors, * fonts, burning speed and other parameters. * * Version: 1.0 * Author: Michael Ryvkin, http://www.ponticstar.com * License: GNU Lesser General Public License, http://www.gnu.org/licenses/lgpl.html * Created: 2010-04-17 * Last updated: 2010-04-17 * Link: http://www.ponticstar.com/projects/burning-words/ */ if(typeof(PonticStar) == "undefined"){ var PonticStar = {}; } PonticStar.BurningWords = function (){ this.interval_id = null; this.palette = null; this.canvas = null; this.stop = function(){ if(this.interval_id !== null) clearInterval(this.interval_id); }; this.show = function(text, text_color, font, font_size, bg_color, bg_alpha, speed, id){ this.stop(); // Define a palette if(this.palette === null){ this.palette = []; for(var i = 0; i < 64; i++){ this.palette[i] = [i * 4, 0, 0]; this.palette[i + 64] = [255, i * 4, 0]; this.palette[i + 128] = [255, 255, i * 4]; this.palette[i + 192] = [255, 255, 255]; } } this.font_string = font_size + "px " + font; this.text = text; this.text_color_string = "rgb(" + parseInt(text_color.substring(0, 2), 16) + "," + parseInt(text_color.substring(2, 4), 16) + "," + parseInt(text_color.substring(4, 6), 16) + ")"; this.bg_color_r = parseInt(bg_color.substring(0, 2), 16); this.bg_color_g = parseInt(bg_color.substring(2, 4), 16); this.bg_color_b = parseInt(bg_color.substring(4, 6), 16); this.bg_color_a = Math.floor(255 * bg_alpha / 100); this.bg_color_a_pct = bg_alpha / 100; this.bg_color_string = "rgba(" + this.bg_color_r + "," + this.bg_color_g + "," + this.bg_color_b + "," + this.bg_alpha + ")"; // If animation speed is given in milliseconds var speed_msec; if(speed && !isNaN(Number(speed)) && speed.toString().match(/^\s+$/) === null){ speed_msec = speed; // Otherwise, if animation speed is given as a keyword } else { switch(speed){ case "x-fast": speed_msec = 10; break; case "fast": speed_msec = 25; break; case "slow": speed_msec = 100; break; case "x-slow": speed_msec = 150; break; default: case "normal": speed_msec = 50; break; } } if(!id){ id = 'text-burning-' + this.counter; } this.counter++; var el = document.getElementById(id); var canvas_id; if(!el){ document.write('<canvas id="' + id + '" style="font-family:' + font + '; font-size:' + font_size + 'px"></canvas>'); canvas_id = id; } else { el.innerHTML = '<canvas id="' + id + '-canvas" style="font-family:' + font + '; font-size:' + font_size + 'px"></canvas>'; canvas_id = id + "-canvas"; } this.canvas = document.getElementById(canvas_id); if(this.canvas.getContext){ var dc = this.canvas.getContext('2d'); dc.font = this.font_string; this.text_size = dc.measureText(text); this.canvas.width = this.text_size.width + 10; this.canvas.height = Math.floor(font_size * 1.5); this.fire_decay = Math.floor(3 + Math.exp(3.6 - font_size/7)); dc.fillStyle = "rgb(0,0,0)"; //bg_color_string; dc.fillRect (0, 0, this.canvas.width, this.canvas.height); this.image = dc.getImageData(0, 0, this.canvas.width, this.canvas.height); dc.fillStyle = "rgb(0,0,0)"; dc.fillRect (0, 0, this.canvas.width, this.canvas.height); this.image_flame = dc.getImageData(0, 0, this.canvas.width, this.canvas.height); // drawing code here dc.fillStyle = "rgb(0,0,0)"; dc.fillRect (0, 0, this.canvas.width, this.canvas.height); dc.fillStyle = "rgb(255,255,255)"; dc.font = this.font_string; dc.textAlign = 'center'; dc.textBaseline = 'bottom'; dc.fillText(text, this.canvas.width/2, this.canvas.height); this.image_src = dc.getImageData(0, 0, this.canvas.width, this.canvas.height); dc.putImageData(this.image, 0, 0); var that = this; this.interval_id = setInterval(function(){ that.burn(); } , speed_msec); } else { el.innerHTML = "Canvas element is not supported"; } }; this.burn = function(){ var dc = this.canvas.getContext('2d'); var image_data_len = this.canvas.width * this.canvas.height * 4; for(var pos = 0; pos < image_data_len; pos+=4){ if(this.image_src.data[pos] == 255){ this.image_flame.data[pos] = Math.floor(Math.random() * 256); } } var incr1 = (this.canvas.width * 4); for(var pos = 0; pos < (image_data_len - incr1); pos+=4){ var x = pos % incr1; var l = this.image_flame.data[ ((x == 0) ? pos + incr1 : pos) - 4 ]; var r = this.image_flame.data[ ((x == incr1 - 4) ? pos - incr1 : pos) + 4 ]; var b = this.image_flame.data[ pos + incr1 ]; var avg = Math.floor((l + r + b + b) / 4); // auto reduce it so you get lest of the forced fade and more vibrant fire waves if (avg > 0){ avg -= this.fire_decay; } // normalize if (avg < 0){ avg = 0; } this.image_flame.data[pos] = avg; } // 4 for 4 ints per pixel for(var pos = 0; pos < image_data_len; pos+=4){ if(this.image_flame.data[pos] != 0){ var c = this.image_flame.data[pos]; var pal = this.palette; var a = (1 - (3 * c)/255); if(a < 0){ a = 0; } if(a > this.bg_color_a){ a = this.bg_color_a; } this.image.data[pos] = Math.min(255, pal[c][0] + Math.floor(this.bg_color_r * a)); this.image.data[pos + 1] = Math.min(255, pal[c][1] + Math.floor(this.bg_color_g * a)); this.image.data[pos + 2] = Math.min(255, pal[c][2] + Math.floor(this.bg_color_b * a)); this.image.data[pos + 3] = Math.max(this.bg_color_a, Math.min(3 * c, 255)); } else { this.image.data[pos] = this.bg_color_r; this.image.data[pos + 1] = this.bg_color_g; this.image.data[pos + 2] = this.bg_color_b; this.image.data[pos + 3] = this.bg_color_a; } } // put pixel data on canvas dc.putImageData(this.image, 0, 0); dc.fillStyle = this.text_color_string; dc.font = this.font_string; dc.textAlign = 'center'; dc.textBaseline = 'bottom'; dc.fillText(this.text, this.canvas.width/2, this.canvas.height); } };