Created
July 4, 2012 02:13
-
-
Save huangxiangdan/3044804 to your computer and use it in GitHub Desktop.
textify.js
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
/** | |
* @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 w() { | |
b = new DAT.GUI({ | |
width: 320 | |
}); | |
a = K(C.ABC); | |
a.redraw = function () { | |
x && y() | |
}; | |
a.save = function () { | |
x && D() | |
}; | |
a.image = function () { | |
p.click() | |
}; | |
z = b.add(a, "preset").name("Preset").options("ABC", "Pointillism", "Mosaic", "Stitch", "@#%", "Bubbles", "StarStruck", "Pixelate", "Binary", "Snow", "Dash").onChange(function (g) { | |
z.removeOption(A); | |
g = C[g]; | |
a.filter = g.filter; | |
a.backgroundColor = g.backgroundColor; | |
a.characterSet = g.characterSet; | |
a.characterLimit = g.characterLimit; | |
a.characterScale = g.characterScale; | |
a.characterFontFamily = g.characterFontFamily; | |
a.characterFontWeight = g.characterFontWeight; | |
b.listen() | |
}); | |
b.add(a, "filter").name("Filter").options("None", "Black & White", "Sepia").listen().onChange(m); | |
b.add(a, "backgroundColor").name("Background").options({ | |
"Dark Grey": "#333", | |
"Light Grey": "#888", | |
Black: "#000", | |
White: "#fff", | |
Red: "#c21a08", | |
Green: "#54ad3c", | |
Blue: "#6c94d2", | |
Transparent: "transparent", | |
"Source Image": "image" | |
}).listen().onChange(m); | |
b.add(a, "characterSet").name("Character Set").listen().onChange(m); | |
b.add(a, "characterLimit").name("Character Quantity").min(1E3).max(1E5).step(500).listen().onChange(m); | |
b.add(a, "characterScale").name("Font Scale").min(0.1).max(5).step(0.1).listen().onChange(m); | |
b.add(a, "characterFontFamily").name("Font Family").options({ | |
Arial: "Arial", | |
"Comic Sans MS": "Comic Sans MS", | |
Helvetica: "Helvetica", | |
monospace: "monospace", | |
"Times New Roman": "Times New Roman" | |
}).listen().onChange(m); | |
guiFontWeight = b.add(a, "characterFontWeight").name("Font Weight").options("normal", "bold", "bolder").listen().onChange(m); | |
b.add(a, "useCanvas").name("Draw on Canvas (<strong>faster</strong>)").listen().onChange(m); | |
L === !1 && (b.add(a, "image").name("Browse for Image"), B = b.add(a, "save").name("Save Image")); | |
E = b.add(a, "redraw").name("Apply Settings"); | |
E.domElement.className += " apply-button"; | |
b.domElement.style.position = "absolute"; | |
b.domElement.style.top = "0px"; | |
b.domElement.style.right = "-20px"; | |
document.querySelector(".guidat-controllers").style.height = "auto"; | |
DAT.GUI.autoPlace = !1; | |
b.autoListen = !1 | |
}function m() { | |
z.prependOption(A, !0); | |
a.preset = A | |
}function K(a) { | |
var l = {}, | |
d; | |
for (d in a) l[d] = a[d]; | |
return l | |
}function F() { | |
k.style.left = (window.innerWidth - j) * 0.5 + "px"; | |
k.style.top = (window.innerHeight - i) * 0.5 + 16 + "px"; | |
f.style.left = (window.innerWidth - f.width) * 0.5 + "px"; | |
f.style.top = (window.innerHeight - f.height) * 0.5 + 16 + "px" | |
}function M() { | |
this.files.length && G(this.files[0]) | |
}function N(a) { | |
a.stopPropagation(); | |
a.preventDefault(); | |
a = a.dataTransfer.files; | |
a.length && G(a[0]) | |
}function G(a) { | |
var l = new FileReader; | |
l.onloadend = O; | |
l.readAsDataURL(a) | |
}function O(g) { | |
g.target.result.match(/^data:image/) ? (a.imageURL = P, c.src = g.target.result, setTimeout(y, 100)) : alert("Unexpected file format, dude.") | |
}function Q(a) { | |
c.onload = function () { | |
x = !0; | |
y() | |
}; | |
c.onerror = function () { | |
alert("Failed to load image with URL " + c.src) | |
}; | |
c.src = a | |
}function y() { | |
s = a.useCanvas; | |
if (a.backgroundColor === "transparent") document.querySelector("html").style.background = 'url("assets/images/transparent-pattern.png")'; | |
else if (a.backgroundColor !== "image") document.querySelector("html").style.background = a.backgroundColor; | |
j = c.width; | |
i = c.height; | |
var g = window.innerWidth * 0.8, | |
l = window.innerHeight * 0.8, | |
d = 1; | |
if (j > g || i > l) d = Math.min(g / j, l / i), j = Math.floor(j * d), i = Math.floor(i * d); | |
k.innerHTML = ""; | |
k.style.width = j + "px"; | |
k.style.height = i + "px"; | |
k.style.fontFamily = a.characterFontFamily; | |
k.style.fontWeight = a.characterFontWeight; | |
o = H * a.characterScale * 1.5; | |
h.restore(); | |
h.clearRect(0, 0, f.width, f.height); | |
h.save(); | |
f.width = j + o * 2; | |
f.height = i + o * 2; | |
if (s) if (a.backgroundColor === "image") h.save(), h.translate(o, o), h.scale(j / c.width, i / c.height), h.drawImage(c, 0, 0, c.width, c.height), h.restore(); | |
else if (a.backgroundColor !== "transparent") h.fillStyle = a.backgroundColor, h.fillRect(0, 0, f.width, f.height); | |
h.translate(o, o); | |
u.width = j; | |
u.height = i; | |
q.save(); | |
q.scale(d, d); | |
q.drawImage(c, 0, 0, c.width, c.height); | |
q.restore(); | |
r = q.getImageData(0, 0, j, i).data; | |
I = r.length / 4; | |
t = []; | |
B && B.name(s ? "Save Image" : "View Source"); | |
F(); | |
J() | |
}function J() { | |
for (var g = a.backgroundColor === "transparent", l = 0; l < R; l++) { | |
var d = Math.floor(Math.random() * I), | |
b = d * 4, | |
c = Math.floor(d / j), | |
d = Math.round((d / j - c) * j), | |
f = Math.round(S + Math.random() * H) * a.characterScale, | |
i = a.characterSet[Math.floor(Math.random() * a.characterSet.length)], | |
e = { | |
r: r[b], | |
g: r[b + 1], | |
b: r[b + 2], | |
a: (0.3 + Math.random() * 0.7).toFixed(2) | |
}, | |
b = r[b + 3] / 255; | |
if (g && b === 0) e.a = 0; | |
if (a.filter === "Black & White") e.r = e.g = e.b = Math.round((e.r + e.g + e.b) / 3); | |
else if (a.filter === "Sepia") e.r = e.g = e.b = Math.round((e.r + e.g + e.b) / 3), e.b = Math.round(e.b * 0.85); | |
s ? (d -= f / 2, c += f / 2, h.save(), h.font = a.characterFontWeight + " " + f + "px " + a.characterFontFamily, h.fillStyle = "rgba(" + e.r + "," + e.g + "," + e.b + ", " + e.a + ")", h.fillText(i, d, c), h.restore(), t.push(i)) : (d -= f / 2, c -= f / 2, b = document.createElement("p"), b.style.left = d + "px", b.style.top = c + "px", b.style.color = "rgba(" + e.r + "," + e.g + "," + e.b + ", " + e.a + ")", b.style.fontSize = f + "px", b.innerHTML = i, k.appendChild(b), t.push(b)) | |
} | |
t.length < a.characterLimit ? (n.style.visibility = "visible", v.style.width = Math.min(t.length / a.characterLimit, 1) * n.offsetWidth + "px", requestAnimFrame(J)) : (n.style.visibility = "hidden", v.style.width = "0px") | |
}function D() { | |
if (s) { | |
var b = window.open("Textify Source", "height=400, width=700, toolbar=no, scrollbars=no, menubar=no"); | |
b.document.write('<img src="' + f.toDataURL() + '"/>') | |
} else { | |
var b = window.open("", "Textify Source", "height=400, width=700, toolbar=no, scrollbars=no, menubar=no"), | |
c = b.document.createElement("textarea"); | |
c.setAttribute("cols", "92"); | |
c.setAttribute("rows", "27"); | |
c.innerHTML += "<style>\n"; | |
c.innerHTML += "\t.textify-output p {\n"; | |
c.innerHTML += "\t\tposition: absolute;\n"; | |
c.innerHTML += "\t}\n"; | |
c.innerHTML += "</style>\n"; | |
var d = b.document.createElement("div"); | |
d.setAttribute("class", "textify-output"); | |
d.style.fontFamily = a.characterFontFamily; | |
d.style.fontWeight = a.characterFontWeight; | |
d.innerHTML += k.innerHTML; | |
c.innerHTML += d.outerHTML; | |
b.document.write(c.outerHTML) | |
} | |
} | |
var R = 1E3, | |
T = ["image1.jpg", "image2.jpg", "image3.jpg", "image4.jpg", "image5.jpg"][Math.floor(Math.random() * 5)], | |
P = "(Drag and drop works too)", | |
A = "Custom", | |
S = 10, | |
H = 15, | |
C = { | |
ABC: { | |
preset: "ABC", | |
filter: "None", | |
useCanvas: !0, | |
characterSet: "ABC", | |
characterLimit: 13E3, | |
characterScale: 1.2, | |
characterFontFamily: "AppleGothic", | |
characterFontWeight: "bold", | |
backgroundColor: "#333" | |
}, | |
Pointillism: { | |
preset: "Pointillism", | |
filter: "None", | |
useCanvas: !0, | |
characterSet: "\u2022", | |
characterLimit: 18E3, | |
characterScale: 2.5, | |
characterFontFamily: "Comic Sans MS", | |
characterFontWeight: "bold", | |
backgroundColor: "#333" | |
}, | |
Mosaic: { | |
preset: "Mosaic", | |
filter: "None", | |
useCanvas: !0, | |
characterSet: "\u25b2\u25bc\u25c0\u25ba\u25c6", | |
characterLimit: 13E3, | |
characterScale: 1.5, | |
characterFontFamily: "Helvetica", | |
characterFontWeight: "normal", | |
backgroundColor: "#333" | |
}, | |
Bubbles: { | |
preset: "Bubbles", | |
filter: "None", | |
useCanvas: !0, | |
characterSet: "oO\u25cc\u25ce", | |
characterLimit: 16E3, | |
characterScale: 1.5, | |
characterFontFamily: "Arial", | |
characterFontWeight: "normal", | |
backgroundColor: "#333" | |
}, | |
"@#%": { | |
preset: "@#%", | |
filter: "None", | |
useCanvas: !0, | |
characterSet: "@#%", | |
characterLimit: 16E3, | |
characterScale: 1.5, | |
characterFontFamily: "monospace", | |
characterFontWeight: "normal", | |
backgroundColor: "#333" | |
}, | |
Pixelate: { | |
preset: "Pixelate", | |
filter: "None", | |
useCanvas: !0, | |
characterSet: "\u25fc", | |
characterLimit: 12E3, | |
characterScale: 1.1, | |
characterFontFamily: "Arial", | |
characterFontWeight: "normal", | |
backgroundColor: "#333" | |
}, | |
Binary: { | |
preset: "Binary", | |
filter: "None", | |
useCanvas: !0, | |
characterSet: "01", | |
characterLimit: 1E4, | |
characterScale: 1.5, | |
characterFontFamily: "Arial", | |
characterFontWeight: "normal", | |
backgroundColor: "#333" | |
}, | |
StarStruck: { | |
preset: "StarStruck", | |
filter: "None", | |
useCanvas: !0, | |
characterSet: "\u2726\u2729\u272a\u272d", | |
characterLimit: 12E3, | |
characterScale: 2, | |
characterFontFamily: "Helvetica", | |
characterFontWeight: "normal", | |
backgroundColor: "#333" | |
}, | |
Snow: { | |
preset: "Snow", | |
filter: "None", | |
useCanvas: !0, | |
characterSet: "\u2746\u2747\u274b", | |
characterLimit: 12E3, | |
characterScale: 2, | |
characterFontFamily: "Arial", | |
characterFontWeight: "normal", | |
backgroundColor: "#333" | |
}, | |
Dash: { | |
preset: "Dash", | |
filter: "None", | |
useCanvas: !0, | |
characterSet: "/\\", | |
characterLimit: 17E3, | |
characterScale: 2, | |
characterFontFamily: "Arial", | |
characterFontWeight: "normal", | |
backgroundColor: "#333" | |
}, | |
Stitch: { | |
preset: "Stitch", | |
filter: "None", | |
useCanvas: !0, | |
characterSet: "\u2716\u2715", | |
characterLimit: 9E3, | |
characterScale: 2, | |
characterFontFamily: "Helvetica", | |
characterFontWeight: "normal", | |
backgroundColor: "#333" | |
} | |
}, | |
a = {}, | |
b, z, B, E, n, v, p, u, q, k, f, h, o = 0, | |
c, r, I, t, j = 1, | |
i = 1, | |
x = !1, | |
s = !1; | |
navigator.userAgent.toLowerCase().match(/ipod/gi); | |
navigator.userAgent.toLowerCase().match(/ipad/gi); | |
navigator.userAgent.toLowerCase().match(/iphone/gi); | |
var L = !! navigator.userAgent.toLowerCase().match(/ipod|ipad|iphone/gi); | |
return { | |
initialize: function () { | |
c = document.createElement("img"); | |
u = document.createElement("canvas"); | |
q = u.getContext("2d"); | |
f = document.createElement("canvas"); | |
f.setAttribute("class", "textify-output-canvas"); | |
h = f.getContext("2d"); | |
k = document.createElement("div"); | |
k.setAttribute("class", "textify-output-html"); | |
n = document.createElement("div"); | |
n.setAttribute("class", "textify-progress"); | |
v = document.createElement("div"); | |
n.appendChild(v); | |
progressText = document.createElement("p"); | |
n.appendChild(progressText); | |
p = document.createElement("input"); | |
p.setAttribute("type", "file"); | |
p.style.visibility = "hidden"; | |
document.body.appendChild(p); | |
document.body.appendChild(f); | |
document.body.appendChild(k); | |
document.body.appendChild(n); | |
window.addEventListener("resize", F, !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", N, !1); | |
p.addEventListener("change", M, !1); | |
w(); | |
Q(T) | |
}, | |
viewSource: D | |
} | |
}(); | |
window.requestAnimFrame = function () { | |
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (w) { | |
window.setTimeout(w, 1E3 / 60) | |
} | |
}(); | |
Textify.initialize(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment