Created
October 7, 2012 01:39
-
-
Save TurplePurtle/3846795 to your computer and use it in GitHub Desktop.
Eye Generator
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"> | |
<title>Eye</title> | |
<style> | |
html, body { background-color: #333; color: #eee; margin: 0; padding: 0; } | |
canvas { background-color: #000; color: #fff; display: block; margin: 16px auto 0; outline: 1px solid #555;} | |
</style> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
// Auxiliary functions | |
function dist(x1, y1, x2, y2, sq) { | |
x2 -= x1; | |
y2 -= y1; | |
return sq ? x2*x2 + y2*y2 : Math.sqrt(x2*x2 + y2*y2); | |
} | |
function dist2(a1, a2) { | |
return dist(a1[0], a1[1], a2[0], a2[1]); | |
} | |
function getCircle(x1, y1, x2, y2, x3, y3, d) { | |
var x1_, y1_, x2_, y2_, m1, b1, m2, b2, xc, yc, r; | |
if (y1 === y2 && y2 === y3) { | |
return false; | |
} | |
// get 2 midpoints | |
x1_ = (x1 + x2) / 2; | |
y1_ = (y1 + y2) / 2; | |
x2_ = (x2 + x3) / 2; | |
y2_ = (y2 + y3) / 2; | |
if (y1 === y2) { | |
xc = x1_; | |
} else { | |
m1 = (x1 - x2) / (y2 - y1); | |
b1 = y1_ - m1 * x1_; | |
} | |
if (y2 === y3) { | |
xc = x2_; | |
} else { | |
m2 = (x2 - x3) / (y3 - y2); | |
b2 = y2_ - m2 * x2_; | |
} | |
if (!xc) { | |
if (m1 === m2) { | |
return false; | |
} | |
xc = (b2 - b1) / (m1 - m2); | |
} | |
yc = m1 ? m1 * xc + b1 : m2 * xc + b2; | |
if (typeof d === "function") { | |
r = d(xc, yc, x1, y1); | |
} else { | |
m1 = xc - x1; // reusing variables | |
m2 = yc - y1; // for radius calculation. | |
r = Math.sqrt(m1*m1 + m2*m2); | |
} | |
return {x: xc, y: yc, r: r}; | |
} | |
// Config | |
var params = {}; | |
params.w = 800; // canvas width | |
params.h = 600; // canvas height | |
// Set up canvas and methods | |
var c = document.createElement("canvas").getContext("2d"); | |
c.canvas.width = params.w; | |
c.canvas.height = params.h; | |
c.fillStyle = "#fff"; | |
c.strokeStyle = "#000"; | |
document.body.appendChild(c.canvas); | |
c.fillCircle = function(x, y, r) { | |
this.beginPath(); | |
this.arc(x, y, r, 0, 6.2832, false); | |
this.fill(); | |
}; | |
c.strokeCircle = function(x, y, r) { | |
this.beginPath(); | |
this.arc(x, y, r, 0, 6.2832, false); | |
this.stroke(); | |
}; | |
c.spline = function(p, t, de) { | |
var j = p.length; | |
if (j < 2) { | |
if (j === 1) { | |
this.fillCircle(p[0][0], p[0][1], 2); | |
} | |
return false; | |
} | |
if (!t) { t = 3; } | |
var cc, cp1, cp2, cp_last = p[0], d, d2 = dist2(p[1], p[0]) / t, i; | |
this.beginPath(); | |
this.moveTo(p[0][0], p[0][1]); | |
for (i = 1; i < j; i++) { | |
// Get control points | |
if (i + 1 === j) { // last point | |
cp1 = p[i]; | |
} else { | |
d = d2; | |
d2 = dist2(p[i+1], p[i]) / t; // Increase denominator for "tighter" spline | |
cc = getCircle(p[i-1][0], p[i-1][1], p[i][0], p[i][1], p[i+1][0], p[i+1][1], dist); | |
if (cc) { | |
cc.angle = Math.atan((cc.x - p[i][0]) / (p[i][1] - cc.y)); | |
} else { | |
cc = {angle: Math.atan((p[i+1][1] - p[i-1][1]) / (p[i+1][0] - p[i-1][0]))}; | |
} | |
cp1 = [p[i][0] - d * Math.cos(cc.angle), p[i][1] - d * Math.sin(cc.angle)]; | |
cp2 = [p[i][0] + d2 * Math.cos(cc.angle), p[i][1] + d2 * Math.sin(cc.angle)]; | |
if (dist2(p[i-1], cp2) + dist2(p[i+1], cp1) < dist2(p[i-1], cp1) + dist2(p[i+1], cp2)) { | |
cp1 = [p[i][0] + d * Math.cos(cc.angle), p[i][1] + d * Math.sin(cc.angle)]; | |
cp2 = [p[i][0] - d2 * Math.cos(cc.angle), p[i][1] - d2 * Math.sin(cc.angle)]; | |
} | |
} | |
// Make curve | |
this.bezierCurveTo(cp_last[0], cp_last[1], cp1[0], cp1[1], p[i][0], p[i][1]); | |
cp_last = cp2; | |
} | |
this.stroke(); | |
if (de) { | |
for (i=0; i < j; i++) { | |
this.fillCircle(p[i][0], p[i][1], 2); | |
} | |
} | |
}; | |
function main() { | |
var w_2 = params.w / 2, h_2 = params.h / 2, bag = {}; | |
bag.r_eye = w_2 - 20; | |
bag.r_iris = bag.r_eye * 5 / 12; | |
bag.r_pupil = bag.r_eye / 6; | |
// White | |
bag.grad = c.createRadialGradient(w_2, h_2, bag.r_iris, w_2, h_2, bag.r_iris+10); | |
bag.grad.addColorStop(0, "#ed0"); | |
bag.grad.addColorStop(0.2, "#dd5"); | |
bag.grad.addColorStop(0.3, "#e3e3a3"); | |
bag.grad.addColorStop(1, "#fff"); | |
c.fillStyle = bag.grad; | |
c.fillCircle(w_2, h_2, bag.r_eye); | |
// Draw and color iris | |
bag.iris = c.createRadialGradient(w_2, h_2, bag.r_pupil, w_2, h_2, bag.r_iris); | |
bag.iris.addColorStop(0.1, "#fa4"); | |
bag.iris.addColorStop(0.4, "#fe0"); | |
bag.iris.addColorStop(0.8, "#fe0"); | |
bag.iris.addColorStop(0.9, "#f6e600"); | |
bag.iris.addColorStop(1, "#ed0"); | |
c.fillStyle = bag.iris; | |
c.fillCircle(w_2, h_2, bag.r_iris); | |
// Make almond shape | |
c.fillStyle = "#222";//"#d95"; | |
bag.circle = getCircle( | |
w_2 - bag.r_eye, h_2, | |
w_2 + bag.r_eye, h_2, | |
w_2, h_2 - bag.r_iris, | |
dist); | |
c.beginPath(); | |
c.arc(bag.circle.x, bag.circle.y, bag.circle.r, Math.PI, 0, false); | |
c.lineTo(bag.circle.x + bag.circle.r, h_2 - bag.r_eye); | |
c.lineTo(bag.circle.x - bag.circle.r, h_2 - bag.r_eye); | |
c.closePath(); | |
c.fill(); | |
bag.circle = getCircle( | |
w_2 - bag.r_eye, h_2, | |
w_2 + bag.r_eye, h_2, | |
w_2, h_2 + bag.r_iris, | |
dist); | |
c.beginPath(); | |
c.arc(bag.circle.x, bag.circle.y, bag.circle.r, 0, Math.PI, false); | |
c.lineTo(bag.circle.x - bag.circle.r, h_2 + bag.r_eye); | |
c.lineTo(bag.circle.x + bag.circle.r, h_2 + bag.r_eye); | |
c.closePath(); | |
c.fill(); | |
//* | |
// Fibers | |
function point(t, d) { return [w_2 + d * Math.cos(t), h_2 + d * Math.sin(t)]; } | |
function mklen(x) { return x.length >= 2 ? x : mklen("0" + x); } // for hex validation | |
function randHex(x, y) { return (x + Math.floor((y+1)*Math.random())).toString(16); } | |
function randColor(_r, _rv, _g, _gv, _b, _bv){ | |
return ["#", mklen(randHex(_r, _rv)), mklen(randHex(_g, _gv)), mklen(randHex(_b, _bv))].join(''); | |
}; | |
var s, i, N, a; | |
// Thin Background lines | |
N = 150; | |
s = 2 * Math.PI / N; | |
c.lineWidth = 2; | |
c.globalAlpha = 0.6; | |
for (i = 0; i < N; i++) { | |
a = [ | |
[w_2, h_2],//point(i * s, bag.r_pupil), | |
point((i - 1.5 + 3*Math.random()) * s, bag.r_pupil + Math.random() * (bag.r_iris - bag.r_pupil) / 3), | |
point((i - 1.5 + 3*Math.random()) * s, bag.r_pupil + (bag.r_iris - bag.r_pupil) / 3 + Math.random() * (bag.r_iris - bag.r_pupil) / 3), | |
point((i - 1 + 2*Math.random()) * s, bag.r_iris-10-15*Math.random()), | |
point((i - 1.5 + 3*Math.random()) * s, bag.r_iris-1) | |
]; | |
bag.grad = c.createRadialGradient(w_2, h_2, bag.r_pupil, w_2, h_2, bag.r_iris); | |
//bag.grad.addColorStop(0, randColor(150, 28, 130, 30, 5, 7)); | |
bag.grad.addColorStop(0, Math.random() > 0.25 ? randColor(230, 25, 230, 15, 0, 8) : randColor(70, 20, 70, 20, 70, 20)); | |
bag.grad.addColorStop(0.25, randColor(180, 28, 160, 30, 8, 7)); | |
bag.grad.addColorStop(0.75, randColor(200, 28, 180, 30, 10, 7)); | |
bag.grad.addColorStop(1, randColor(200, 28, 180, 30, 10, 7)); | |
c.strokeStyle = bag.grad; | |
c.spline(a, 5); | |
} | |
// Thick lines | |
N = 100; | |
s = 2 * Math.PI / N; | |
c.globalAlpha = 0.75; | |
for (i = 0; i < N; i++) { | |
if (Math.random() > 0.3) { | |
bag.grad = c.createRadialGradient(w_2, h_2, bag.r_pupil, w_2, h_2, bag.r_iris); | |
bag.grad.addColorStop(0.05 + 0.1*Math.random(), randColor(200, 15, 170, 30, 10, 15)); | |
bag.grad.addColorStop(0.2 + .25*Math.random(), Math.random() > 0.5 ? randColor(220, 20, 125, 20, 40, 15) : randColor(200, 30, 180, 30, 10, 7)); | |
bag.grad.addColorStop(0.5, randColor(200, 30, 180, 30, 10, 7)); | |
bag.grad.addColorStop(0.8, randColor(185, 40, 165, 30, 8, 7)); | |
bag.grad.addColorStop(1, randColor(175, 30, 155, 30, 10, 7)); | |
c.strokeStyle = bag.grad; | |
} | |
if (Math.random() > 0.4) { | |
c.lineWidth = 3 + Math.floor(Math.random()*2); | |
} | |
a = [ | |
[w_2, h_2],//point(i * s, bag.r_pupil), | |
point((i - 1.5 + 3*Math.random()) * s, bag.r_pupil + Math.random() * (bag.r_iris - bag.r_pupil) / 3), | |
point((i - 1.5 + 3*Math.random()) * s, bag.r_pupil + (bag.r_iris - bag.r_pupil) / 3 + Math.random() * (bag.r_iris - bag.r_pupil) / 3), | |
point((i - 1 + 2*Math.random()) * s, bag.r_iris-10-15*Math.random()), | |
point((i - 1 + 2*Math.random()) * s, bag.r_iris-1) | |
]; | |
c.spline(a, 5); | |
a = [ | |
[w_2, h_2],//point(i * s, bag.r_pupil), | |
point((i - 1.5 + 3*Math.random()) * s, bag.r_pupil + Math.random() * (bag.r_iris - bag.r_pupil) / 3), | |
point((i - 1.5 + 3*Math.random()) * s, bag.r_pupil + (bag.r_iris - bag.r_pupil) / 3 + Math.random() * (bag.r_iris - bag.r_pupil) / 3), | |
point((i - 1 + 2*Math.random()) * s, bag.r_iris-10-15*Math.random()), | |
point((i - 1 + 2*Math.random()) * s, bag.r_iris-1) | |
]; | |
c.spline(a, 5); | |
} | |
//*/ | |
// Pupil | |
c.globalAlpha = 1; | |
c.fillStyle = c.strokeStyle = "#111"; | |
c.fillCircle(w_2, h_2, bag.r_pupil); | |
c.globalAlpha = 0.75; | |
c.lineWidth = 4; | |
c.strokeCircle(w_2, h_2, bag.r_pupil); | |
} | |
main(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment