const P = require('p5'); const sketch = function (p) { let canvas; const dMouse = []; let closest = 0; let isEditMode = true; let fillHSlider, fillSSlider, fillBSlider, fillOSlider; let fillHValue, fillSValue, fillBValue, fillOValue; let strokeHSlider, strokeSSlider, strokeBSlider, strokeOSlider; let strokeHValue, strokeSValue, strokeBValue, strokeOValue; let editButton; let saveDrawingButton; let indexUoButton; let indexDownButton; let completeButton; let undoButton; let deleteButton; let shapes = [ { fill_H: p.random(360), fill_S: 50, fill_B: 100, fill_O: 100, stroke_H: p.random(360), stroke_S: 50, stroke_B: 100, stroke_O: 100, indices: [] } ]; let shapeIndex = 0; let tParameters; let isDraggedOver = false; p.setup = function () { canvas = p.createCanvas(cameraWidth, cameraHeight); canvas.id('canvas'); canvas.dragOver(() => { isDraggedOver = true; }); canvas.dragLeave(() => { isDraggedOver = false; }); canvas.drop(file => { if (file.subtype === 'json') { shapes = file.data.shapes; shapeIndex = shapes.length - 1; isDraggedOver = false; } else { isDraggedOver = false; } }); p.colorMode(p.HSB, 360, 100, 100, 100); editButton = p.createButton('Edit mode off'); editButton.mousePressed(p.toggleEdit); editButton.class('Buttons'); editButton.id('editButton'); fillHValue = p.createDiv(); fillHValue.class('valueDisplay'); fillHSlider = p.createSlider(0, 360, p.random(360), 5); fillHSlider.class('Slider'); fillSValue = p.createDiv(); fillSValue.class('valueDisplay'); fillSSlider = p.createSlider(0, 100, 50, 5); fillSSlider.class('Slider'); fillBValue = p.createDiv(); fillBValue.class('valueDisplay'); fillBSlider = p.createSlider(0, 100, 100, 5); fillBSlider.class('Slider'); fillOValue = p.createDiv(); fillOValue.class('valueDisplay'); fillOSlider = p.createSlider(0, 100, 100, 5); fillOSlider.class('Slider'); strokeHValue = p.createDiv(); strokeHValue.class('valueDisplay'); strokeHSlider = p.createSlider(0, 360, p.random(360), 5); strokeHSlider.class('Slider'); strokeSValue = p.createDiv(); strokeSValue.class('valueDisplay'); strokeSSlider = p.createSlider(0, 100, 50, 5); strokeSSlider.class('Slider'); strokeBValue = p.createDiv(); strokeBValue.class('valueDisplay'); strokeBSlider = p.createSlider(0, 100, 100, 5); strokeBSlider.class('Slider'); strokeOValue = p.createDiv(); strokeOValue.class('valueDisplay'); strokeOSlider = p.createSlider(0, 100, 100, 5); strokeOSlider.class('Slider'); saveDrawingButton = p.createButton(''); saveDrawingButton.mousePressed(p.saveDrawing); saveDrawingButton.class('imageButtons'); saveDrawingButton.id('saveDrawingButton'); indexUoButton = p.createButton(''); indexUoButton.mousePressed(p.upIndex); indexUoButton.class('imageButtons'); indexUoButton.id('indexUoButton'); indexDownButton = p.createButton(''); indexDownButton.mousePressed(p.downIndex); indexDownButton.class('imageButtons'); indexDownButton.id('indexDownButton'); completeButton = p.createButton('complete'); completeButton.mousePressed(p.complete); completeButton.class('Buttons'); completeButton.id('completeButton'); undoButton = p.createButton('undo'); undoButton.mousePressed(p.undo); undoButton.class('Buttons'); undoButton.id('undoButton'); deleteButton = p.createButton('delete'); deleteButton.mousePressed(p.deleteDrawing); deleteButton.class('Buttons'); deleteButton.id('deleteButton'); tParameters = { fill_H: fillHSlider.value(), fill_S: fillSSlider.value(), fill_B: fillBSlider.value(), fill_O: fillOSlider.value(), stroke_H: strokeHSlider.value(), stroke_S: strokeSSlider.value(), stroke_B: strokeBSlider.value(), stroke_O: strokeOSlider.value() }; p.textAlign(p.CENTER, p.CENTER); p.textSize(24); }; p.draw = function () { p.clear(); if (detections !== undefined) { if (detections.faceLandmarks !== undefined && detections.faceLandmarks.length >= 1) { p.drawShapes(); if (isEditMode === true) { p.faceMesh(); p.editShapes(); } if (isDraggedOver === true) { p.noStroke(); p.fill(0, 0, 100, 10); p.rect(0, 0, p.width, p.height); p.fill(0, 0, 100); // p.text('Drag your drawing here', p.width / 2, p.height / 2); } } } fillHValue.html('fill hue: ' + fillHSlider.value()); fillSValue.html('fill saturation: ' + fillSSlider.value()); fillBValue.html('fill brightness: ' + fillBSlider.value()); fillOValue.html('fill opacity: ' + fillOSlider.value()); strokeHValue.html('stroke hue: ' + strokeHSlider.value()); strokeSValue.html('stroke saturation: ' + strokeSSlider.value()); strokeBValue.html('stroke brightness: ' + strokeBSlider.value()); strokeOValue.html('stroke opacity: ' + strokeOSlider.value()); }; p.faceMesh = function () { p.stroke(0, 0, 100); p.strokeWeight(3); p.beginShape(p.POINTS); for (let i = 0; i < detections.faceLandmarks[0].length; i++) { const x = detections.faceLandmarks[0][i].x * p.width; const y = detections.faceLandmarks[0][i].y * p.height; p.vertex(x, y); const d = p.dist(x, y, p.mouseX, p.mouseY); dMouse.push(d); } p.endShape(); const minimum = p.min(dMouse); closest = dMouse.indexOf(minimum); p.stroke(0, 100, 100); p.strokeWeight(10); p.point(detections.faceLandmarks[0][closest].x * p.width, detections.faceLandmarks[0][closest].y * p.height); dMouse.splice(0, dMouse.length); }; p.mouseClicked = function () { if (p.mouseX >= 0 && p.mouseX <= p.width) { if (p.mouseY >= 0 && p.mouseY <= p.height) { if (isEditMode === true) { shapes[shapeIndex].indices.push(closest); console.log(shapes); } } } }; p.drawShapes = function () { for (let s = 0; s < shapes.length; s++) { p.fill(shapes[s].fill_H, shapes[s].fill_S, shapes[s].fill_B, shapes[s].fill_O); p.stroke(shapes[s].stroke_H, shapes[s].stroke_S, shapes[s].stroke_B, shapes[s].stroke_O); p.strokeWeight(3); if (isEditMode === true) { if (s === shapeIndex) p.glow('rgba(255, 255, 255, 100)'); else p.glow('rgba(255, 255, 255, 0)'); } else if (isEditMode === false) { p.glow('rgba(255, 255, 255, 100)'); } p.beginShape(); for (let i = 0; i < shapes[s].indices.length; i++) { p.vertex( detections.faceLandmarks[0][shapes[s].indices[i]].x * p.width, detections.faceLandmarks[0][shapes[s].indices[i]].y * p.height ); } p.endShape(); } }; p.editShapes = function () { // --- fill --- if (tParameters.fill_H !== fillHSlider.value()) { tParameters.fill_H = fillHSlider.value(); shapes[shapeIndex].fill_H = fillHSlider.value(); } if (tParameters.fill_S !== fillSSlider.value()) { tParameters.fill_S = fillSSlider.value(); shapes[shapeIndex].fill_S = fillSSlider.value(); } if (tParameters.fill_B !== fillBSlider.value()) { tParameters.fill_B = fillBSlider.value(); shapes[shapeIndex].fill_B = fillBSlider.value(); } if (tParameters.fill_O !== fillOSlider.value()) { tParameters.fill_O = fillOSlider.value(); shapes[shapeIndex].fill_O = fillOSlider.value(); } // --- stroke --- if (tParameters.stroke_H !== strokeHSlider.value()) { tParameters.stroke_H = strokeHSlider.value(); shapes[shapeIndex].stroke_H = strokeHSlider.value(); } if (tParameters.stroke_S !== strokeSSlider.value()) { tParameters.stroke_S = strokeSSlider.value(); shapes[shapeIndex].stroke_S = strokeSSlider.value(); } if (tParameters.stroke_B !== strokeBSlider.value()) { tParameters.stroke_B = strokeBSlider.value(); shapes[shapeIndex].stroke_B = strokeBSlider.value(); } if (tParameters.stroke_O !== strokeOSlider.value()) { tParameters.stroke_O = strokeOSlider.value(); shapes[shapeIndex].stroke_O = strokeOSlider.value(); } }; p.keyTyped = function () { if (p.key === 'e') p.toggleEdit(); if (p.key === 'c') p.complete(); if (p.key === 'z') p.undo(); if (p.key === 'd') p.deleteDrawing(); if (p.key === 'j') p.saveDrawing(); }; p.toggleEdit = function () { isEditMode = !isEditMode; if (isEditMode === true) { editButton.html('Edit mode on'); } else if (isEditMode === false) { editButton.html('Edit mode off'); } }; p.complete = function () { if (shapes[shapes.length - 1].indices.length > 0) { if (shapes[shapeIndex].indices.length === 0 && shapes.length > 1) shapes.splice(shapeIndex, 1); shapes.push({ fill_H: p.random(360), fill_S: 50, fill_B: 100, fill_O: 100, stroke_H: p.random(360), stroke_S: 50, stroke_B: 100, stroke_O: 100, indices: [] }); shapeIndex = shapes.length - 1; } console.log(shapes); }; p.undo = function () { if (shapes[shapeIndex] !== undefined) { if (shapes[shapeIndex].indices.length > 0) shapes[shapeIndex].indices.pop(); } console.log(shapes[shapeIndex].indices); }; p.deleteDrawing = function () { shapes = [ { fill_H: p.random(360), fill_S: 50, fill_B: 100, fill_O: 100, stroke_H: p.random(360), stroke_S: 50, stroke_B: 100, stroke_O: 100, indices: [] } ]; shapeIndex = 0; console.log(shapes); }; p.saveDrawing = function () { const s = { shapes }; p.saveJSON(s, 'untitled_shapes.json'); }; p.keyPressed = function () { if (p.keyCode === p.UP_ARROW) p.upIndex(); else if (p.keyCode === p.DOWN_ARROW) p.downIndex(); }; p.upIndex = function () { if (shapes[shapeIndex] !== undefined) { if (shapes[shapeIndex].indices.length === 0 && shapes.length > 1) shapes.splice(shapeIndex, 1); if (shapeIndex < shapes.length - 1) shapeIndex++; p.resetSliders(); console.log(shapeIndex); } }; p.downIndex = function () { if (shapes[shapeIndex] !== undefined) { if (shapes[shapeIndex].indices.length === 0 && shapes.length > 1) shapes.splice(shapeIndex, 1); if (shapeIndex > 0) shapeIndex--; p.resetSliders(); console.log(shapeIndex); } }; p.resetSliders = function () { fillHSlider.value(shapes[shapeIndex].fill_H); fillSSlider.value(shapes[shapeIndex].fill_S); fillBSlider.value(shapes[shapeIndex].fill_B); fillOSlider.value(shapes[shapeIndex].fill_O); strokeHSlider.value(shapes[shapeIndex].stroke_H); strokeSSlider.value(shapes[shapeIndex].stroke_S); strokeBSlider.value(shapes[shapeIndex].stroke_B); strokeOSlider.value(shapes[shapeIndex].stroke_O); }; p.glow = function (glowColor) { p.drawingContext.shadowOffsetX = 0; p.drawingContext.shadowOffsetY = 0; p.drawingContext.shadowBlur = 20; p.drawingContext.shadowColor = glowColor; }; }; const myp5 = new P(sketch);