Start image in center then follow mouse?

Hi. How could I edit this code so that when a person loads the page the image is in the center but then once they click/touch the image follows the mouse cursor/finger? Currently the image follows the cursor but that means that when the page is loaded for the first time the image is all the way up in the top left hand corner of the screen.

let img;
let song;

function windowResized() 
{
  resizeCanvas(windowWidth, windowHeight);
}


function preload()
{
song = loadSound('assets/sound.m4a');
}

function setup() 
{
createCanvas(windowWidth, windowHeight);

imageMode(CENTER);

img =  loadImage('assets/image.png');
song = loadSound('assets/sound.m4a');

frameRate(12);
}

function mousePressed() 
  {
  getAudioContext().resume() 
  song.play();
  }
  
function mouseMoved() 
  {
  song.play();
  }
  
function touchStarted() 
  {
  getAudioContext().resume() 
  song.play();
  }
  
function touchMoved() 
  {
  song.play();
  }
  
  
function draw() 
{
  var mX=mouseX
  var mY=mouseY

image(img, mX, mY, img.width / 2,     
  img.height / 2);
    
}

Is the image accessible in setup()?

I recommend watching the video Boolean Variables. It’s a bit long, but it’s a clear explanation of combining booleans with different type of mouse functions. In your case you could use the boolean to switch the x and y location of the image.

Hope that helps.

2 Likes

yes, the start mouse X Y is 0,0

you can avoid that only by some tricky code:
-a- start with a
boolean mDrag = false;
-b- draw the image at the center canvas
-c- if mouse ( first time ) over image enable
mDrag = true;
-d- with that draw the image at mouseX, mouseY

1 Like

I am very new to all of this, but I just recently did the very thing you are trying.

The variables need to be declared outside of any function, then called within the if(mouseIsPressed){}, which is within draw()

Such as:

var mX =
var mY =

function draw(){

if (mouseIsPressed){
    mX = mouseX;
    mY = mouseY;
}  

}

This was a snippet of code I played with from Khan Academy to achieve that result:

var eyeSize = 35;
var x = 200;
var y = 200;

function setup() {
createCanvas(400, 450);
noStroke();
}

function draw() {
background(240);

// face
fill(255, 255, 0);
ellipse(x, y, 300, 300);
        
// eyes
fill(46, 46, 41);
ellipse(x - 50, y-50, eyeSize, eyeSize);
ellipse(x + 100, y-55, eyeSize, eyeSize);
        
// mouth
fill(252, 65, 65);
ellipse(x + 50, y+40, 120, 136); 
  
if (mouseIsPressed){
    x = mouseX;
    y = mouseY;
}

}

1 Like

For whatever reasons I can’t get this to work at all…
When I set the initial variables as

var mX=windowWidth/2;
var mY=windowHeight/2;

It only works if I pasted that into draw. It won’t work anywhere else, only if I use numbers…

I think so? That’s all the code above. I set the img variable and load it in setup if that’s what you mean.

I’ve still not been able to get this to work. Anyone have any other ideas? I wonder why it works for mbrasseau but not on my end?

It seems as if mouseMoved isn’t enough to trigger moving an image. Could that be a bug? The above code works on mouseIsPressed but not mouseMoved.

did you test?

follow only when mouse pressed and moved

https://p5js.org/reference/#/p5/mouseDragged

https://editor.p5js.org/kll/sketches/L4da3ypJO

Ok I found a work around. I can use a function as follows:

set the variables so that they’re global

var mX = 200;
var mY = 200;

Then setup the draw function

function draw()
{

image(imageVAR, mX, mY, imageVAR.width / 2,
imageVAR.height / 2);
}

Then setup the mouseMoved function outside the draw function as well

function mouseMoved()
{
mX = mouseX;
mY = mouseY;
soundVAR.play();
}

But for whatever reason this doesn’t work when I set the mX and mY variables to windowWidth/2 and windowHeight/2. When I do that the image won’t follow the mouse cursor. The log is telling me that windowWidth isn’t defined.

Nice example thanks…trying it now.

please note that in your ( and my old code / now revised )
the image is resized 60 times per sec / bad idea
( image parameter 4,5 )

use only one time ( like in setup )
https://p5js.org/reference/#/p5.Image/resize

1 Like

I don’t know what you mean.

Ok here is my final code, which achieves everything (edit: almost everything, see Play sound on muted iPhone) I’ve wanted to and is my first completed project :grinning:
I’m not sure if it’s properly written but at least it all works. If you see any poorly written or redundant code please let me know!

The image starts out in the center of the screen,
when the mouse is clicked or the screen is touched in draws the image again and plays a sound,
then when the mouse is moved or a touch is moved it re-draws the image across the screen and plays the sound.

let imageVAR;
let soundVAR;


function preload()
{
imageVAR =  loadImage('assets/face.png');
soundVAR = loadSound('assets/soundfx.mp3');
}


function setup() 
{
var cnv = createCanvas(windowWidth, windowHeight);
cnv.style('display', 'block');

imageMode(CENTER);

mX = width/2;
mY = height/2;
frameRate(12);
}

  
function draw() 
{
background(5);

image(imageVAR, mX, mY, imageVAR.width / 2,     
  imageVAR.height / 2);
}


function mousePressed() 
  {
  mX = mouseX;
  mY = mouseY;
  getAudioContext().resume() 
  soundVAR.play();
  }
  
function mouseMoved() 
  {
	mX = mouseX;
    mY = mouseY;
  soundVAR.play();
  }
  
function touchStarted() 
  {
   mX = mouseX;
  mY = mouseY;
  getAudioContext().resume() 
  soundVAR.play();
  }
  
function touchMoved() 
  {
  mX = mouseX;
  mY = mouseY;
  soundVAR.play();
  return false;
  }

function windowResized() 
{
  resizeCanvas(windowWidth, windowHeight);
}

1 Like

There is a certain order in which p5 executes its code. It gathers all the global variables before running setup. If you tried to give a global variable a value related to the canvas size, it won’t work since the canvas size isn’t set yet. A way to tackle this is by declaring it as a variable, but initializing it in setup:

var myX;
var myY;

function setup() {
  createCanvas(400, 450);
  myX = width / 2;
  myY = height / 2;
}

function draw() {
  // rest of your code
}
1 Like