Skip to content

Instantly share code, notes, and snippets.

@TurplePurtle
Created October 7, 2012 01:39
Show Gist options
  • Save TurplePurtle/3846795 to your computer and use it in GitHub Desktop.
Save TurplePurtle/3846795 to your computer and use it in GitHub Desktop.
Eye Generator
<!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