// TOTAL RIPOFF OF FIZZYTEXT // https://github.com/dataarts/dat.gui/blob/gh-pages/docs/demo.js // (still has a ton of vestigial elements thereof) function StreakyText(message) { var that = this; // These are the variables that we manipulate with gui-dat. // Notice they're all defined with "this". That makes them public. // Otherwise, gui-dat can't see them. this.growthSpeed = 0.4; // how fast do particles change size? this.minV = .4; this.maxV = 2; // how big can they get? this.noiseStrength = 10; // how turbulent is the flow? this.speed = 0.4; // how fast do particles move? this.displayOutline = false; // should we draw the message as a stroke? this.framesRendered = 0; //////////////////////////////////////////////////////////////// var _this = this; var width = 550; var height = 200; var textAscent = 101; var textOffsetLeft = 20; var noiseScale = 300; var frameTime = 30; var colors = ["#00aeff", "#0fa954", "#54396e", "#e61d5f"]; // This is the context we use to get a bitmap of text using // the getImageData function. var r = document.createElement('canvas'); var s = r.getContext('2d'); // This is the context we actually use to draw. var c = document.createElement('canvas'); var g = c.getContext('2d'); // And this one is used to leave behind the 'streaks'; it doesn't get cleared, see... var c2 = document.createElement('canvas'); var g2 = c2.getContext('2d'); r.setAttribute('width', width); c.setAttribute('width', width); c2.setAttribute('width', width); r.setAttribute('height', height); c.setAttribute('height', height); c2.setAttribute('height', height); // Add our demo to the HTML document.getElementById('streakytext').appendChild(c); document.getElementById('streakytext').appendChild(c2); // Stores bitmap image var pixels = []; // Stores a list of particles var particles = []; // Set g.font to the same font as the bitmap canvas, incase we // want to draw some outlines. s.font = g.font = g2.font = "800 82px helvetica, arial, sans-serif"; // g2.fillStyle = 'rgba(0, 0, 0, 0.2)'; g2.globalAlpha = .1; // Instantiate some particles for (var i = 0; i < 1000; i++) { particles.push(new Particle(Math.random() * width, Math.random() * height - height)); } // This function creates a bitmap of pixels based on your message // It's called every time we change the message property. var createBitmap = function (msg) { s.fillStyle = "#fff"; s.fillRect(0, 0, width, height); s.fillStyle = "#222"; s.fillText(msg, textOffsetLeft, textAscent); // Pull reference var imageData = s.getImageData(0, 0, width, height); pixels = imageData.data; }; // Called once per frame, updates the animation. var render = function () { that.framesRendered ++; g.clearRect(0, 0, width, height); if (_this.displayOutline) { g.globalCompositeOperation = "source-over"; g.strokeStyle = "#000"; g.lineWidth = .5; g.strokeText(message, textOffsetLeft, textAscent); } g.globalCompositeOperation = "darker"; g2.globalCompositeOperation = "darker"; for (var i = 0; i < particles.length; i++) { g.fillStyle = colors[i % colors.length]; g2.fillStyle = colors[i % colors.length]; particles[i].render(); } }; // Returns x, y coordinates for a given index in the pixel array. var getPosition = function (i) { return { x: (i - (width * 4) * Math.floor(i / (width * 4))) / 4, y: Math.floor(i / (width * 4)) }; }; // Returns a color for a given pixel in the pixel array. var getColor = function (x, y) { var base = (Math.floor(y) * width + Math.floor(x)) * 4; var c = { r: pixels[base + 0], g: pixels[base + 1], b: pixels[base + 2], a: pixels[base + 3] }; return "rgb(" + c.r + "," + c.g + "," + c.b + ")"; }; this.message = message; createBitmap(message); var loop = function() { requestAnimationFrame(loop); render(); } // This calls the render function every 30 milliseconds. loop(); // This class is responsible for drawing and moving those little // colored dots. function Particle(x, y, c) { // Position this.x = x; this.y = y; // Size of particle this.r = 1.5; this.v = .1; this.constrain = function (v, o1, o2) { if (v < o1) v = o1; else if (v > o2) v = o2; return v; }; // Called every frame this.render = function () { // What color is the pixel we're sitting on top of? var c = getColor(this.x, this.y); // Are we within the boundaries of the image? var onScreen = this.x > 0 && this.x < width && this.y > 0 && this.y < height; var isBlack = c != "rgb(255,255,255)" && onScreen; // If we're on top of a black pixel, slow. // If not, speed up. if (isBlack) { this.v -= _this.growthSpeed; // this.r = 1.5; } else { this.v += _this.growthSpeed; // this.r = 1; } this.v = this.constrain(this.v, _this.minV, _this.maxV); this.y += this.v; // Once we fall off the bottom, respawn at random x-coord along top // if(this.y > height) { // this.x = Math.random() * width; // this.y = 0; // } // Draw the circle. g.beginPath(); g.arc(this.x, this.y, this.r, 0, Math.PI * 2, false); g.fill(); // Draw the streak. if(isBlack) { g2.beginPath(); g2.arc(this.x, this.y, this.r, 0, Math.PI * 2, false); g2.fill(); } } } }