const detection_options = {
const mouthOpenThreshold = 30;
let colorPicker1, colorPicker2, colorPicker3, colorPicker4, colorPicker5, colorPicker6, colorPicker7;
let drawShapesWithDifferentColors = false;
let drawShapesWithCustomColors = false;
let drawWaterAndFire = false;
exp1 = createP("Hello! This place is for you to try different");
exp1.position(width -300 , height - 300);
exp2 = createP("type of masks and while having fun you can")
exp2.position(width -300 , height - 280);
exp3 = createP("also get inspiration. First you can try different")
exp3.position(width-300 , height - 260);
exp4 = createP("type of masks we have already created for you");
exp4.position(width-300 , height - 240);
exp5 = createP("- be ready for surprises-. And of course with ")
exp5.position(width-300, height - 220);
exp6 = createP("our custom mask designer you can make your")
exp6.position(width-300, height - 200);
exp7 = createP("own mask with the color you wish to use");
exp7.position(width-300 , height -180);
button1 = createButton('Sun and Moon');
button1.position(width + 700, height - 300);
button1.mousePressed(toggleDrawing);
button1.style('background-color', '#000');
button1.style('color', '#fff');
button2 = createButton('Angel and Devil');
button2.position(width + 700, height - 200);
button2.mousePressed(toggleDifferentColors);
button2.style('background-color', '#000');
button2.style('color', '#fff');
button3 = createButton('Custom Mask');
button3.position(width + 850, height - 300);
button3.mousePressed(toggleCustomColors);
button3.style('background-color', '#000');
button3.style('color', '#fff');
button4 = createButton('Water And Fire');
button4.position(width + 700, height - 100);
button4.mousePressed(toggleWaterAndFire);
button4.style('background-color', '#000');
button4.style('color', '#fff');
colorPicker1 = createColorPicker('#000');
colorPicker1.position(width + 850, height - 250);
colorPicker2 = createColorPicker('#fff');
colorPicker2.position(width + 850, height - 210);
colorPicker3 = createColorPicker('#fff');
colorPicker3.position(width + 850, height - 170);
colorPicker4 = createColorPicker('#fff');
colorPicker4.position(width + 850, height - 130);
colorPicker5 = createColorPicker('#fff');
colorPicker5.position(width + 850, height - 90);
colorPicker6 = createColorPicker('#fff');
colorPicker6.position(width + 850, height - 50);
colorPicker7 = createColorPicker('#fff');
colorPicker7.position(width + 850, height - 10);
outsideText1 = createP("Face");
outsideText1.position(width + 930, height - 260);
outsideText2 = createP("Face Stroke");
outsideText2.position(width + 930, height - 220);
outsideText3 = createP("Eyes");
outsideText3.position(width + 930, height - 180);
outsideText4 = createP("Eyebrows");
outsideText4.position(width + 930, height - 140);
outsideText5 = createP("Nose");
outsideText5.position(width + 930, height - 100);
outsideText6 = createP("Mouth");
outsideText6.position(width + 930, height - 60);
outsideText7 = createP("Cheeks");
outsideText7.position(width + 930, height - 20);
video = createCapture(VIDEO);
video.size(width, height);
faceapi = ml5.faceApi(video, detection_options, modelReady);
faceapi.detect(gotResults);
function toggleDrawing() {
drawShapes = !drawShapes;
drawShapesWithDifferentColors = false;
drawShapesWithCustomColors = false;
drawWaterAndFire = false;
button1.style('background-color', '#ffb700');
button2.style('background-color', '#000');
button3.style('background-color', '#000');
button4.style('background-color', '#000');
button2.style('color', '#fff');
button1.style('background-color', '#000');
button2.style('color', '#fff');
function toggleDifferentColors() {
drawShapesWithDifferentColors = !drawShapesWithDifferentColors;
drawWaterAndFire = false;
drawShapesWithCustomColors = false;
if (drawShapesWithDifferentColors) {
button2.style('background-color', '#fff');
button1.style('background-color', '#000');
button3.style('background-color', '#000');
button4.style('background-color', '#000');
button2.style('color', '#000');
button2.style('background-color', '#000');
button2.style('color', '#fff');
function toggleCustomColors() {
drawShapesWithCustomColors = !drawShapesWithCustomColors;
drawWaterAndFire = false;
drawShapesWithDifferentColors = false;
if (drawShapesWithCustomColors) {
button3.style('background-color', '#c1121f');
button1.style('background-color', '#000');
button2.style('background-color', '#000');
button4.style('background-color', '#000');
button2.style('color', '#fff');
button3.style('background-color', '#000');
button2.style('color', '#fff');
function toggleWaterAndFire() {
drawWaterAndFire = !drawWaterAndFire;
drawShapesWithDifferentColors = false;
drawShapesWithCustomColors = false;
button4.style('background-color', '#003399');
button1.style('background-color', '#000');
button2.style('background-color', '#000');
button3.style('background-color', '#000');
button2.style('color', '#fff');
button4.style('background-color', '#000');
button2.style('color', '#fff');
function gotResults(err, result) {
image(video, 0, 0, width, height);
if (detect && detections) {
if (detections.length > 0) {
drawLandmarks(detections);
faceapi.detect(gotResults);
function drawBox(detections) {
for (let i = 0; i < detections.length; i++) {
const alignedRect = detections[i].alignedRect;
const mouth = detections[i].parts.mouth;
const mouthWidth = dist(mouth[0]._x, mouth[0]._y, mouth[mouth.length - 1]._x, mouth[mouth.length - 1]._y);
const x = alignedRect._box._x;
const y = alignedRect._box._y;
const centerX = x + alignedRect._box._width / 2;
const centerY = y + alignedRect._box._height / 2 - 20;
const boxWidth = alignedRect._box._width;
const boxHeight = alignedRect._box._height;
if (mouthWidth > mouthOpenThreshold) {
for (let j = 0; j < 360; j += 30) {
const angle = radians(j);
const lineLength = alignedRect._box._width * 1.5;
const endX = centerX + cos(angle) * lineLength;
const endY = centerY + sin(angle) * lineLength;
line(centerX, centerY, endX, endY);
ellipse(centerX, centerY, alignedRect._box._width * 1.5, alignedRect._box._height * 1.5);
drawCheeks(detections[i]);
if (drawShapesWithDifferentColors) {
if (mouthWidth > mouthOpenThreshold) {
const aboveHeadY = centerY - boxHeight / 2 - 30;
ellipse(centerX, aboveHeadY - 50, boxWidth * 1, boxHeight / 3);
ellipse(centerX, centerY, boxWidth * 1.5, boxHeight * 1.5);
drawCheeks(detections[i]);
if (mouthWidth > mouthOpenThreshold) {
ellipse(centerX, centerY, alignedRect._box._width * 1.5, alignedRect._box._height * 1.5);
let ellipseWidth1 = alignedRect._box._width * 1.5;
let ellipseHeight1 = alignedRect._box._height * 1.5;
let numSmallCircles1 = 70;
for (let i = 0; i < numSmallCircles1; i++) {
let angle = TWO_PI / numSmallCircles1 * i;
let x = centerX + (ellipseWidth1 / 2) * cos(angle);
let y = centerY + (ellipseHeight1 / 2) * sin(angle);
let smallCircleRadius1 = random(45, 65);
line(centerX, centerY, x, y);
ellipse(x, y, smallCircleRadius1, smallCircleRadius1);
ellipse(centerX, centerY, alignedRect._box._width * 1.5, alignedRect._box._height * 1.5);
let ellipseWidth = alignedRect._box._width * 1.5;
let ellipseHeight = alignedRect._box._height * 1.5;
let numSmallCircles = 70;
for (let i = 0; i < numSmallCircles; i++) {
let angle = TWO_PI / numSmallCircles * i;
let x = centerX + (ellipseWidth / 2) * cos(angle);
let y = centerY + (ellipseHeight / 2) * sin(angle);
let smallCircleRadius = random(45, 50);
ellipse(x, y, smallCircleRadius, smallCircleRadius);
if (drawShapesWithCustomColors) {
fill(colorPicker1.color());
stroke(colorPicker2.color());
ellipse(centerX, centerY, alignedRect._box._width * 1.5, alignedRect._box._height * 1.5);
drawCheeks(detections[i]);
if (drawShapesWithDifferentColors && mouthWidth > mouthOpenThreshold) {
drawRockTriangles(detections[i]);
function drawCheeks(detection) {
const leftCheek = detection.parts.leftEye[0];
const rightCheek = detection.parts.rightEye[3];
if (drawShapes || drawShapesWithCustomColors) {
fill(drawShapesWithCustomColors ? colorPicker7.color() : color(255, 143, 171));
ellipse(leftCheek._x - 20, leftCheek._y + 40, cheekRadius * 2, cheekRadius * 2);
ellipse(rightCheek._x + 20, rightCheek._y + 40, cheekRadius * 2, cheekRadius * 2);
if (drawShapesWithDifferentColors) {
ellipse(leftCheek._x - 20, leftCheek._y + 20, cheekRadius * 3 - 20, cheekRadius * 2 - 20);
ellipse(rightCheek._x + 20, rightCheek._y + 20, cheekRadius * 3 - 20, cheekRadius * 2 - 20);
function drawRockTriangles(detection) {
const alignedRect = detection.alignedRect;
const x = alignedRect._box._x;
const y = alignedRect._box._y;
const boxWidth = alignedRect._box._width;
const boxHeight = alignedRect._box._height;
const leftX = x + boxWidth / 4;
const rightX = x + 3 * boxWidth / 4;
triangle(leftX - 50, topY, leftX + 10, topY, leftX - 20, topY - 80);
triangle(rightX - 10, topY, rightX + 50, topY, rightX + 20, topY - 80);
function drawLandmarks(detections) {
if (!drawShapes && !drawShapesWithDifferentColors && !drawShapesWithCustomColors && !drawWaterAndFire) return;
for (let i = 0; i < detections.length; i++) {
const mouth = detections[i].parts.mouth;
const nose = detections[i].parts.nose;
const leftEye = detections[i].parts.leftEye;
const rightEye = detections[i].parts.rightEye;
const rightEyeBrow = detections[i].parts.rightEyeBrow;
const leftEyeBrow = detections[i].parts.leftEyeBrow;
drawPart(leftEyeBrow, false);
drawPart(rightEye, true);
drawPart(rightEyeBrow, false);
function drawPart(feature, closed) {
if (!drawShapes && !drawShapesWithDifferentColors && !drawShapesWithCustomColors && !drawWaterAndFire) return;
for (let i = 0; i < feature.length; i++) {
if (drawShapesWithDifferentColors || drawShapesWithCustomColors || drawWaterAndFire) {
rightEyeBrow: drawShapesWithCustomColors ? colorPicker4.color() : (drawShapesWithDifferentColors ? color(255) : color(0)),
leftEyeBrow: drawShapesWithCustomColors ? colorPicker4.color() : (drawShapesWithDifferentColors ? color(255) : color(0)),
nose: drawShapesWithCustomColors ? colorPicker5.color() : (drawShapesWithDifferentColors ? color(0) : color(255)),
rightEye: drawShapesWithCustomColors ? colorPicker3.color() : (drawShapesWithDifferentColors ? color(72, 202, 228) : color(72, 202, 228)),
leftEye: drawShapesWithCustomColors ? colorPicker3.color() : (drawShapesWithDifferentColors ? color(72, 202, 228) : color(72, 202, 228)),
mouth: drawShapesWithCustomColors ? colorPicker6.color() : (drawShapesWithDifferentColors ? color(0) : color(208, 0, 0)),
for (let part in colorMap) {
if (feature === detections[0].parts[part]) {
for (let i = 0; i < feature.length; i++) {