xxxxxxxxxx
105
let facemesh;
let video;
let predictions = [];
let partyMode = false;
let colorA, colorB, currentColor;
let confetti = [];
let gravity = 20;
function setup() {
createCanvas(640, 480);
video = createCapture(VIDEO);
video.size(width, height);
facemesh = ml5.facemesh(video, modelReady);
facemesh.on("predict", results => {
predictions = results;
checkMouthOpen();
});
video.hide();
colorA = color(random(255), random(255), random(255), 126); // starting color
colorB = color(random(255), random(255), random(255), 126); // next color
currentColor = colorA;
}
function modelReady() {
console.log("Model ready!");
}
function draw() {
if (partyMode) {
tint(currentColor);
updateColor();
addConfetti();
} else {
noTint();
}
image(video, 0, 0, width, height);
updateAndDrawConfetti();
}
function checkMouthOpen() {
if (predictions.length > 0) {
const keypoints = predictions[0].scaledMesh;
const topLip = keypoints[13];
const bottomLip = keypoints[14];
const distance = dist(topLip[0], topLip[1], bottomLip[0], bottomLip[1]);
if (distance > 20) {
partyMode = true;
} else {
partyMode = false;
}
}
}
function updateColor() {
if (frameCount % 60 === 0) {
colorA = colorB;
colorB = color(random(255), random(255), random(255), 126);
}
currentColor = lerpColor(colorA, colorB, (frameCount % 60) / 60);
}
function addConfetti() {
if (frameCount % 2 === 0) {
confetti.push(new Confetti());
}
}
function updateAndDrawConfetti() {
for (let i = confetti.length - 1; i >= 0; i--) {
confetti[i].update();
confetti[i].draw();
if (confetti[i].y > height | !partyMode) {
confetti.splice(i, 1);
}
}
}
class Confetti {
constructor() {
this.x = random(width);
this.y = random(-50, -10);
this.size = random(5, 15);
this.color = color(random(255), random(255), random(255));
this.velY = random(1, 2);
}
update() {
this.y += this.velY + gravity;
}
draw() {
fill(this.color);
noStroke();
ellipse(this.x, this.y, this.size, this.size);
}
}