Created
May 24, 2011 20:43
-
-
Save teeler/989620 to your computer and use it in GitHub Desktop.
Textify
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// via http://textify.it/ | |
/** | |
* @author Hakim El Hattab | |
* | |
* Recreates bitmap images using HTML text. Images are | |
* drawn onto a canvas element so that the pixels can | |
* be read. Letters, with colors matching the image pixels, | |
* are then placed at random locations on the screen. | |
*/ | |
var Textify = function () { | |
function q() { | |
b.monochrome = !1; | |
b.maintainAlpha = !1; | |
b.imageURL = r; | |
b.characterSet = A; | |
b.characterLimit = 15E3; | |
b.characterScale = 1; | |
b.characterFontFamily = "Arial"; | |
b.characterFontWeight = "normal"; | |
b.image = function () { | |
j.click() | |
}; | |
b.redraw = function () { | |
b.imageURL !== c.src && b.imageURL !== r && b.imageURL.length > 4 ? u(b.imageURL) : s ? t() : alert("You'll need to load an image first.") | |
}; | |
b.viewSource = function () { | |
s ? v() : alert("You'll need to load an image first.") | |
}; | |
var a = new DAT.GUI; | |
a.add(b, "image").name("Browse For Image"); | |
a.add(b, "monochrome").name("Black & White"); | |
a.add(b, "maintainAlpha").name("Maintain Alpha"); | |
a.add(b, "characterSet").name("Character Set"); | |
a.add(b, "characterLimit").name("Character Quantity").min(1E3).max(1E5).step(500); | |
a.add(b, "characterScale").name("Font Scale").min(0.1).max(5).step(0.1); | |
a.add(b, "characterFontFamily").name("Font Family").options("Arial", "Helvetica", "Times New Roman", "Lucida Grande", "Comic Sans MS", "monospace"); | |
a.add(b, "characterFontWeight").name("Font Weight").options("normal", "bold", "bolder"); | |
a.add(b, "viewSource").name("View source"); | |
var d = a.add(b, "redraw").name("APPLY SETTINGS"); | |
d.domElement.style.height = "32px"; | |
d.domElement.style.backgroundColor = "rgb(10,150,150)"; | |
d.domElement.style.fontSize = "14px"; | |
a.domElement.style.position = "absolute"; | |
a.domElement.style.top = "42px"; | |
a.domElement.style.right = "-15px"; | |
document.querySelector(".guidat-controllers").style.height = "auto" | |
} | |
function w() { | |
f.style.left = (window.innerWidth - g) * 0.5 + "px"; | |
f.style.top = (window.innerHeight - e) * 0.5 + "px" | |
} | |
function B() { | |
console.log(this.files[0]); | |
this.files.length && x(this.files[0]) | |
} | |
function C(a) { | |
a.stopPropagation(); | |
a.preventDefault(); | |
a = a.dataTransfer.files; | |
a.length && x(a[0]) | |
} | |
function x(a) { | |
var b = new FileReader; | |
b.onloadend = D; | |
b.readAsDataURL(a) | |
} | |
function D(a) { | |
a.target.result.match(/^data:image/) ? (b.imageURL = r, c.src = a.target.result, setTimeout(t, 100)) : alert("Unexpected file format, dude.") | |
} | |
function u(a) { | |
c.onload = function () { | |
s = !0; | |
t() | |
}; | |
c.onerror = function () { | |
alert("Failed to load image with URL " + c.src) | |
}; | |
c.src = a | |
} | |
function t() { | |
g = c.width; | |
e = c.height; | |
var a = window.innerWidth * 0.8, | |
d = window.innerHeight * 0.8, | |
h = 1; | |
if (g > a || e > d) h = Math.min(a / g, d / e), g = Math.floor(g * h), e = Math.floor(e * h); | |
f.innerHTML = ""; | |
f.style.width = g + "px"; | |
f.style.height = e + "px"; | |
f.style.fontFamily = b.characterFontFamily; | |
f.style.fontWeight = b.characterFontWeight; | |
n.width = g; | |
n.height = e; | |
l.save(); | |
l.scale(h, h); | |
l.drawImage(c, 0, 0, c.width, c.height); | |
l.restore(); | |
m = l.getImageData(0, 0, g, e).data; | |
y = m.length / 4; | |
o = []; | |
w(); | |
z() | |
} | |
function z() { | |
for (var a = "", d = 0; d < E; d++) { | |
var h = Math.floor(Math.random() * y), | |
c = h * 4, | |
e = Math.floor(h / g), | |
h = Math.round((h / g - e) * g), | |
j = Math.round(10 + Math.random() * 10) * b.characterScale; | |
h -= j / 2; | |
e -= j / 2; | |
var i = { | |
r: m[c], | |
g: m[c + 1], | |
b: m[c + 2], | |
a: (0.3 + Math.random() * 0.7).toFixed(2) | |
}; | |
if (b.maintainAlpha) i.a = m[c + 3]; | |
if (b.monochrome) i.r = i.g = i.b = Math.round((i.r + i.g + i.b) / 3); | |
c = '<p style="left: ' + h + "px; top: " + e + "px; font-size: " + j + "px; color: rgba(" + i.r + "," + i.g + "," + i.b + ", " + i.a + ')">' + b.characterSet[Math.floor(Math.random() * b.characterSet.length)] + "</p>"; | |
a += c; | |
o.push(c) | |
} | |
d = document.createElement("div"); | |
d.style.position = "fixed"; | |
d.innerHTML = a; | |
f.appendChild(d); | |
o.length < b.characterLimit ? (k.style.visibility = "visible", p.style.width = Math.min(o.length / b.characterLimit, 1) * k.offsetWidth + "px", requestAnimFrame(z)) : (k.style.visibility = "hidden", p.style.width = "0px") | |
} | |
function v() { | |
var a = window.open("", "Textify Source", "height=400, width=700, toolbar=no, scrollbars=no, menubar=no"), | |
d = a.document.createElement("textarea"); | |
d.setAttribute("cols", "92"); | |
d.setAttribute("rows", "27"); | |
d.innerHTML += "<style>\n"; | |
d.innerHTML += "\t.textify-output p {\n"; | |
d.innerHTML += "\t\tposition: absolute;\n"; | |
d.innerHTML += "\t}\n"; | |
d.innerHTML += "</style>\n"; | |
var c = a.document.createElement("div"); | |
c.setAttribute("class", "textify-output"); | |
c.style.fontFamily = b.characterFontFamily; | |
c.style.fontWeight = b.characterFontWeight; | |
c.innerHTML += f.innerHTML; | |
d.innerHTML += c.outerHTML; | |
a.document.write(d.outerHTML) | |
} | |
var E = 1E3, | |
r = "(Drag and drop works too)", | |
A = "@%#", | |
n, l, k, p, j, f, c, m, y, o, g = 1, | |
e = 1, | |
s = !1, | |
b = {}; | |
return { | |
initialize: function () { | |
c = document.createElement("img"); | |
n = document.createElement("canvas"); | |
l = n.getContext("2d"); | |
f = document.createElement("div"); | |
f.setAttribute("class", "textify-output"); | |
k = document.createElement("div"); | |
k.setAttribute("class", "textify-progress"); | |
p = document.createElement("div"); | |
k.appendChild(p); | |
progressText = document.createElement("p"); | |
k.appendChild(progressText); | |
j = document.createElement("input"); | |
j.setAttribute("type", "file"); | |
j.style.visibility = "hidden"; | |
document.body.appendChild(j); | |
document.body.appendChild(f); | |
document.body.appendChild(k); | |
window.addEventListener("resize", w, !1); | |
document.addEventListener("dragover", function (a) { | |
a.preventDefault() | |
}, !1); | |
document.addEventListener("dragenter", function (a) { | |
a.preventDefault() | |
}, !1); | |
document.addEventListener("dragexit", function (a) { | |
a.preventDefault() | |
}, !1); | |
document.addEventListener("drop", C, !1); | |
j.addEventListener("change", B, !1); | |
q(); | |
u("image3.jpg") | |
}, | |
viewSource: v | |
} | |
}(); | |
window.requestAnimFrame = function () { | |
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || | |
function (q) { | |
window.setTimeout(q, 1E3 / 60) | |
} | |
}(); | |
Textify.initialize(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment