xxxxxxxxxx
123
let handPose;
let video;
let hands = [];
let pendulum; // The swinging ball
function preload() {
handPose = ml5.handPose();
}
function setup() {
createCanvas(640, 480);
video = createCapture(VIDEO);
video.size(640, 480);
video.hide();
// Start detecting hands from the webcam video
handPose.detectStart(video, gotHands);
// Initialize the pendulum
pendulum = new Pendulum(width / 2, 100);
}
function draw() {
background(220);
// Draw webcam feed
image(video, 0, 0, width, height);
let targetDirection = 0; // -1 = left-up, 1 = right-up, 0 = return to center
for (let i = 0; i < hands.length; i++) {
let hand = hands[i];
for (let j = 0; j < hand.keypoints.length; j++) {
let keypoint = hand.keypoints[j];
fill(0, 255, 0);
noStroke();
circle(keypoint.x, keypoint.y, 10);
}
// Detect the middle index finger tip (keypoint[8])
let indexFinger = hand.keypoints[8];
if (indexFinger) {
if (indexFinger.x < width / 2) {
targetDirection = -1; // Left-up movement
} else {
targetDirection = 1; // Right-up movement
}
}
}
// Apply movement based on hand position
if (targetDirection === -1) {
pendulum.moveLeftUp();
} else if (targetDirection === 1) {
pendulum.moveRightUp();
} else {
pendulum.returnToCenter();
}
// Update and display the pendulum
pendulum.update();
pendulum.display();
}
// Callback function for when handPose outputs data
function gotHands(results) {
hands = results;
}
// Pendulum Class (Only Moves Left-Up or Right-Up)
class Pendulum {
constructor(x, y) {
this.origin = createVector(x, y); // Fixed point
this.position = createVector(x, y + 150); // Ball position
this.angle = 0; // Start at rest
this.aVelocity = 0;
this.aAcceleration = 0;
this.damping = 0.95; // Smooth movement
this.followSpeed = 0.05; // Smooth animation
this.maxHeight = y + 50; // How high the ball moves
this.restingHeight = y + 150; // Default bottom position
this.targetHeight = this.restingHeight; // Initial position
}
moveLeftUp() {
this.angle = lerp(this.angle, -PI / 4, this.followSpeed); // Move left
this.targetHeight = this.maxHeight; // Move up
}
moveRightUp() {
this.angle = lerp(this.angle, PI / 4, this.followSpeed); // Move right
this.targetHeight = this.maxHeight; // Move up
}
returnToCenter() {
this.angle = lerp(this.angle, 0, this.followSpeed); // Swing back to center
this.targetHeight = this.restingHeight; // Slowly return to bottom
}
update() {
// Smoothly transition the ball to the target height
this.position.y = lerp(this.position.y, this.targetHeight, this.followSpeed);
// Update ball position based on angle
this.position.x = this.origin.x + sin(this.angle) * 150;
}
display() {
// Draw the pendulum rod
stroke(0);
strokeWeight(2);
line(this.origin.x, this.origin.y, this.position.x, this.position.y);
// Draw the swinging ball
fill(255, 0, 0);
noStroke();
ellipse(this.position.x, this.position.y, 20, 20);
}
}