Makes eyes follow mouse cursor

I’m fairly new to coding, but for a project I’m working on, I’m trying to make a pair of eyes that will follow my mouse cursor.
I want the eyes to look at roughly where I point my cursor, while also staying inside the eye sockets. After some tinkering I got it to this stage, which is kind of like what I want it to be like. So far I’ve it so that the distance between the eyeballs don’t change, but the problem now is that I also want them to move in towards each other when the mouse goes between the eyes, and I have not a clue where to start. Maybe with vectors? Any suggestions are appreciated.
Apologies for bad coding.

Code

var halfWidth
var halfHeight

function setup() {
  createCanvas(400, 400);
  ellipseMode(CENTER);
  angleMode(DEGREES);
  rectMode(CENTER);
  noStroke();
  colorMode(HSB);
  halfWidth = width / 2;
  halfHeight = height / 2;
}


function draw() {
  background(0, 0, 50);
  translate(halfWidth, halfHeight);
  scale(1, -1);
  eyes();
}

function eyes() {
  fill(0, 0, 100);
  mEllipse(40, 0, 0, 0, 0, 50);
  //Corrected mouse position
  var adjustedX = mouseX - width / 2;
  var adjustedY = -(mouseY - height / 2);

  var xOffset = 40;
  var yOffset = 0;
  var highlightOffset = 5;
  var mapRadius = 12;

  //Distance from center of eye sockets to mouse
  var d = dist(0, 0, adjustedX, adjustedY);

  //Mapping, restrict mouse to a square centered on the face (the square is turned into a circle down below)
  //50px buffer border arond the canvas
  var x1 = map(adjustedX, -halfWidth + 50, halfWidth - 50, -mapRadius, mapRadius, true);
  var y1 = map(adjustedY, -halfHeight + 50, halfHeight - 50, -mapRadius, mapRadius, true);

  //If distance from center to adjustedMouse is less than mapRadius, use mapped mouse coordinates,
  //else, map to closest point on the restricted circle.
  if (dist(0, 0, x1, y1) <= mapRadius) {
    fill(1, 0, 30);
    mEllipse(xOffset, 0, 0, x1, y1, 20);
    //Highlight
    fill(0, 0, 100);
    mEllipse(xOffset, 0, highlightOffset, x1, y1, 7);
  }
  else {
    fill(1, 0, 30);
    mEllipse(xOffset, 0, 0, findPoint(-mapRadius, 0, adjustedX, d), findPoint(-mapRadius, 0, adjustedY, d), 20)
    //Highlight
    fill(0, 0, 100);
    mEllipse(xOffset, 0, highlightOffset, findPoint(-mapRadius, 0, adjustedX, d), findPoint(-mapRadius, 0, adjustedY, d), 7)
  }
}

//Draw mirrored ellipse pairs to save 1 line of code
function mEllipse(xOffset, yOffset, g, x, y, r1, r2) {
  ellipse(x + xOffset + g, y + yOffset + g, r1, r2);
  ellipse(x - xOffset + g, y - yOffset + g, r1, r2);
}

//Formula for closest point on circle:
//(r*(x0-x)/d, r*(y0-y)/d) --> Radius * (origin - point) / distance
function findPoint(radius, p0, p1, distance) {
  return(radius * (p0 - p1) / distance);
}
2 Likes

nice look. something quick and dirty you could change to something like this i haven’t included the shifting pupils but that should be fairly easy

1 Like

I’ve thought about this, but decided against it because I couldn’t figure out how to use this while letting the pupils move freely within the eyes. I think I might be missing something obvious

sorry i didn’t fully think this through. i mean it’s easy enough to get the pupils to move as in your original by adjusting the radius used in the placement of the pupils like this unfortunately it negates the ability of the eyes to turn inwards when the mouse is centred and we’re back to where you started :confused: i am sure there is a way to handle that but it escapes me at the moment. i believe this is the same problem you have with your code as the distance reaches zero they are unable to turn inward i’m guessing you would need some kind of scale where as the distance reduces the scale increases and vice versa when the distances increases and then you would mutliply the distance by that scale. sorry i couldn’t be of help but i’m sure someone will have a solution for you.