Direct Link
Source code
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> |
| <html> |
| <head> |
| <title>mistakes - Interactive DHTML art-demos</title> |
| <meta name="Author" content="Gerard Ferrandez at http://www.dhteumeuleu.com"> |
| <meta http-equiv="imagetoolbar" content="no"> |
| <style type="text/css"> |
| html { |
| overflow: hidden; |
| } |
| body { |
| background: #000; |
| width: 100%; |
| height: 100%; |
| color: #fff; |
| } |
| #frm { |
| position: absolute; |
| height: 60%; |
| width: 70%; |
| left: 15%; |
| top: 20%; |
| font-size: 2em; |
| font-weight: bold; |
| font-family: verdana, arial; |
| background: #111; |
| overflow: hidden; |
| padding: 0.5em; |
| } |
| #frm span { |
| position: relative; |
| text-align: center; |
| z-index: 1; |
| } |
| #mtxform { |
| position: relative; |
| z-index: 10; |
| } |
| .hidden { |
| visibility: hidden; |
| } |
| </style> |
| <script type="text/javascript"> |
| /* |
| ========================================================================== |
| script: morphing text |
| author: Gerard Ferrandez - [Ge1doot] |
| date: 20 September, 2008 |
| site: http://www.dhteumeuleu.com |
| inspiration: http://www.pwang.com/blog/archives/2006/04/post_100.html |
| quote: Scott Adams, 'The Dilbert Principle' |
| ------------ |
| license: CC-BY-NC - please do not remove this notice ! |
| ========================================================================== |
| */ |
| var mtx = function () { |
| /* ==== private variables & methods ==== */ |
| var stop = false; |
| var frm, lineDelay, charDelay; |
| var colorText, colorMatch, colorGhost, elapsedTime; |
| var lineIndex = 0; |
| var lineChar = []; |
| var animStack = []; |
| var colorStack = []; |
| /* ==== rgb color ==== */ |
| function colorRGB (c) { |
| return 'rgb(' |
| +Math.round(Math.min(255, Math.max(0, c[0])))+',' |
| +Math.round(Math.min(255, Math.max(0, c[1])))+',' |
| +Math.round(Math.min(255, Math.max(0, c[2])))+')'; |
| } |
| /* ==== Easing functions ==== */ |
| function Ease () {} |
| Ease.prototype = { |
| ease : function () { |
| this.m += this.s; |
| this.x0 += (this.d * this.m * .0025); |
| if (this.m == 20) this.s = -1; |
| return this.x0; |
| }, |
| init : function (x0, x1) { |
| this.m = 0; |
| this.s = 1; |
| this.d = x1 - x0; |
| this.x0 = x0; |
| } |
| } |
| /* ==== Load Lines ==== */ |
| function loadLines () { |
| // read text from HTML form |
| text = document.forms.mtxform.text.value.split("\n"); |
| // loop through all lines |
| for (var j = 0; j < text.length; j++) { |
| var t = text[j]; |
| if (t) { |
| var n = t.length; |
| lineChar[j] = []; |
| // first pass: create characters capture RELATIVE offset coordinates |
| for (var i = 0; i < n; i++) |
| lineChar[j][i] = new Character(t.charAt(i), j); |
| // second pass: convert to absolute position |
| for (var i = 0, o; o = lineChar[j][i]; i++) { |
| if (o.c == "|") { |
| // remove spaces |
| lineChar[j].splice(i, 1); |
| frm.removeChild(o.o); |
| i--; |
| } else { |
| // convert to absolute position and render |
| o.o.style.position = "absolute"; |
| o.o.style.color = colorRGB(colorText); |
| o.moveHTML(); |
| // push first line in animation stack |
| if (j == 0) pushAnim (o, charDelay * i); |
| } |
| } |
| } |
| } |
| } |
| /* ==== Character Constructor ==== */ |
| function Character (c, line) { |
| if (c == " ") c = "|"; |
| this.c = c; |
| // create HTML element and append the the container |
| this.o = document.createElement("span"); |
| this.o.innerHTML = c; |
| this.o.style.zIndex = 2; |
| frm.appendChild(this.o); |
| // capture relative offset positions ! |
| this.x0 = this.o.offsetLeft; |
| this.y0 = -this.o.offsetHeight * 1.5; |
| this.x1 = this.x0; |
| this.x2 = this.x0; |
| this.y1 = (line + 1) * this.o.offsetHeight; |
| this.y2 = frm.offsetHeight; |
| this.mx = new Ease(); |
| this.my = new Ease(); |
| this.c0 = [colorText[0], colorText[1], colorText[2]]; |
| } |
| /* ==== Character functions ==== */ |
| Character.prototype = { |
| // ---- character animation ---- |
| anim : function (i) { |
| // temporization |
| if (this.delay > 0) { |
| if (elapsedTime) |
| this.delay -= new Date().getTime() - elapsedTime; |
| } else { |
| // moving |
| this.x0 = this.mx.ease(); |
| this.y0 = this.my.ease(); |
| this.moveHTML(); |
| if (!this.my.m && !this.mx.m) { |
| // remove from stack |
| animStack.splice(i, 1); |
| // remove dead characters |
| if (this.off) frm.removeChild(this.o); |
| } |
| } |
| }, |
| // ----- color fading ------ |
| color : function (i) { |
| this.c0[0] += this.cr[0]; |
| this.c0[1] += this.cr[1]; |
| this.c0[2] += this.cr[2]; |
| this.ci++; |
| this.o.style.color = colorRGB(this.c0); |
| if (this.ci >= this.cs) |
| colorStack.splice(i, 1); |
| }, |
| // ----- HTML positioning ----- |
| moveHTML : function () { |
| this.o.style.left = Math.round(this.x0) + "px"; |
| this.o.style.top = Math.round(this.y0) + "px"; |
| }, |
| // ----- init color fading ------ |
| colorFade : function (c1, steps) { |
| this.cs = steps; |
| this.cr = [(c1[0] - this.c0[0]) / steps, (c1[1] - this.c0[1]) / steps, (c1[2] - this.c0[2]) / steps]; |
| if (this.cr[0] != 0 || this.cr[1] != 0 || this.cr[2] != 0){ |
| this.ci = 0; |
| colorStack.push (this); |
| } |
| } |
| } |
| /* ==== push character in the animation stack ==== */ |
| function pushAnim (o, delay) { |
| // init ease |
| o.mx.init(o.x0, o.x1); |
| o.my.init(o.y0, o.y1); |
| o.delay = delay; |
| // push stack |
| animStack.push(o); |
| } |
| /* ==== next line ==== */ |
| function nextLine () { |
| if (lineIndex < lineChar.length - 1) { |
| // display shadow text |
| for (var i = 0, o; o = lineChar[lineIndex][i]; i++) { |
| var s = o.o.cloneNode(true); |
| s.style.zIndex = 1; |
| s.style.color = colorRGB(colorGhost); |
| frm.appendChild(s); |
| } |
| // matching next line characters |
| for (var i = 0, t; t = lineChar[lineIndex + 1][i]; i++) { |
| for (var j = 0, o; o = lineChar[lineIndex][j]; j++) { |
| if (o.c == t.c) { |
| // colors |
| t.colorFade(colorMatch, o.match ? 1 : 40); |
| t.match = true; |
| // swap characters |
| t.x0 = o.x0; |
| t.y0 = o.y0; |
| t.moveHTML(); |
| // remove redundant character |
| frm.removeChild(o.o); |
| lineChar[lineIndex].splice(j, 1); |
| break; |
| } |
| } |
| } |
| // take off redundant characters |
| for (var i = 0, o; o = lineChar[lineIndex][i]; i++) { |
| // set target position (off frame) |
| o.y1 = frm.offsetHeight; |
| o.off = true; |
| o.match = false; |
| o.colorFade (colorText, 40); |
| // push in animation stack |
| pushAnim (o, (lineDelay * .8) + charDelay * i); |
| } |
| } |
| // push next line in animation stack |
| lineIndex++; |
| if (lineIndex < lineChar.length) { |
| for (var i = 0, o; o = lineChar[lineIndex][i]; i++) |
| pushAnim (o, lineDelay + charDelay * i); |
| } |
| } |
| /* ==== main animation loop ==== */ |
| function main() { |
| // characters |
| var n = animStack.length; |
| if (n) { |
| var i = n; |
| while (i--) |
| animStack[i].anim(i); |
| } else nextLine (); |
| // colors |
| var i = colorStack.length; |
| while (i--) |
| colorStack[i].color(i); |
| // get elapsed time and loop |
| elapsedTime = new Date().getTime(); |
| setTimeout(main, 16); |
| } |
| /* //////////// ==== public methods ==== //////////// */ |
| return { |
| /* ==== initialize script ==== */ |
| init : function (cont, t1, t2, c1, c2, c3) { |
| // container |
| frm = document.getElementById(cont); |
| lineDelay = t1; |
| charDelay = t2; |
| colorText = c1; |
| colorMatch = c2; |
| colorGhost = c3; |
| loadLines(); |
| main(); |
| }, |
| changeText : function () { |
| document.getElementById("show").className = ""; |
| document.getElementById("inputext").className = "hidden"; |
| lineChar = []; |
| animStack = []; |
| colorStack = []; |
| frm.innerHTML = ""; |
| lineIndex = 0; |
| elapsedTime = 0; |
| loadLines(); |
| frm.focus(); |
| }, |
| show : function () { |
| document.getElementById("show").className = "hidden"; |
| document.getElementById("inputext").className = ""; |
| document.getElementById("text").focus(); |
| } |
| } |
| }(); |
| /* ==== init text ==== */ |
| onload = function () { |
| // mtx.init( el, linesDelay, charsDelay, cText, cMatch, cGhost); |
| mtx.init("frm", 1500, 150, [255,255,255], [255,64,0], [44,44,44]); |
| } |
| </script> |
| </head> |
| <body> |
| <div id="frm"></div> |
| <form id="mtxform" name="mtxform"> |
| <button id="show" type="button" onclick="mtx.show();">Replay</button> |
| <br> |
| <span id="inputext" class="hidden"> |
| <textarea rows="6" cols="46" id="text" name="text"> |
| Creativity is allowing yourself |
| to make mistakes. |
| Art is knowing |
| which ones to keep. |
| </textarea><br> |
| <button type="button" onclick="mtx.changeText();">Play</button> |
| <input type="RESET"> |
| </span> |
| </form> |
| </body> |
| </html> |


Recent Comments
March 20, 2011 (2:39)
March 20, 2011 (2:36)
March 20, 2011 (1:27)
// mtx.init( el, linesDelay, charsDelay, cText, cMatch, cGhost); mtx.init("frm", 1500, 150, [64,64,64], [255,64,0], [180,200,255]);As an example: http://www.dhteumeuleu.com/dhtml/textmorph-white.html hope this helps