p5.js sketch that finds eye positions from the webcam and draws a representation of their movement, with random colors for the irises.
Click on the canvas to save an image; press a key to clear the canvas.
This sketch was very helpful in getting started with clmtrackr 🙏
<html>
<head>
<meta charset="UTF-8">
<title>Eye trails</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js"></script>
<script src="https://www.auduno.com/clmtrackr/build/clmtrackr.min.js"></script>
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>
let capture = null;
let tracker = null;
let positions = null;
let w = 0, h = 0;
function setup() {
w = windowWidth;
h = windowHeight;
capture = createCapture(VIDEO);
createCanvas(w, h);
capture.size(w, h);
capture.hide();
frameRate(10);
colorMode(HSB);
background(0);
tracker = new clm.tracker();
tracker.init();
tracker.start(capture.elt);
}
function draw() {
// Flip the canvas so that we get a mirror image
translate(w, 0);
scale(-1.0, 1.0);
// Uncomment the line below to see the webcam image (and no trail)
//image(capture, 0, 0, w, h);
positions = tracker.getCurrentPosition();
if (positions.length > 0) {
// Eye points from clmtrackr:
// https://www.auduno.com/clmtrackr/docs/reference.html
const eye1 = {
outline: [23, 63, 24, 64, 25, 65, 26, 66].map(getPoint),
center: getPoint(27),
top: getPoint(24),
bottom: getPoint(26)
};
const eye2 = {
outline: [28, 67, 29, 68, 30, 69, 31, 70].map(getPoint),
center: getPoint(32),
top: getPoint(29),
bottom: getPoint(31)
}
const irisColor = color(random(360), 80, 80, 0.4);
drawEye(eye1, irisColor);
drawEye(eye2, irisColor);
}
}
function getPoint(index) {
return createVector(positions[index][0], positions[index][1]);
}
function drawEye(eye, irisColor) {
noFill();
stroke(255, 0.4);
drawEyeOutline(eye);
const irisRadius = min(eye.center.dist(eye.top), eye.center.dist(eye.bottom));
const irisSize = irisRadius * 2;
noStroke();
fill(irisColor);
ellipse(eye.center.x, eye.center.y, irisSize, irisSize);
const pupilSize = irisSize / 3;
fill(0, 0.6);
ellipse(eye.center.x, eye.center.y, pupilSize, pupilSize);
}
function drawEyeOutline(eye) {
beginShape();
const firstPoint = eye.outline[0];
eye.outline.forEach((p, i) => {
curveVertex(p.x, p.y);
if (i === 0) {
// Duplicate the initial point (see curveVertex documentation)
curveVertex(firstPoint.x, firstPoint.y);
}
if (i === eye.outline.length - 1) {
// Close the curve and duplicate the closing point
curveVertex(firstPoint.x, firstPoint.y);
curveVertex(firstPoint.x, firstPoint.y);
}
});
endShape();
}
function keyPressed() {
// Clear background
background(0);
}
function mouseClicked() {
const timestamp = timestampString();
saveCanvas("eyeTrail-" + timestamp, "png");
}
function timestampString() {
return year() + nf(month(), 2) + nf(day(), 2) + "-" + nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2);
}
function windowResized() {
w = windowWidth;
h = windowHeight;
resizeCanvas(w, h);
background(0);
}