Simulate Mouse Cursor Delay?

edited October 2013 in Questions about Code

Hey All,

Having the hardest time simulating a delayed mouse cursor.

It ALMOST works, but keeps flashing, then last point disappears.

I want the delayed cursor (ellipse) to draw just as smoothly and remain just as the non-delayed one (rectangle). But the delayed one is choppy, flashing and eventually disappears. (I actually want to remove the rectangle and keep the lagged cursor only);

I've tried using delay() and sleep(), framerate() and vector lerp(), etc, to try and smooth this out, (probably in all the wrong ways).

I know it may have to do with my array storing method, sampling rate (there are multiple coordinates for one ms time), and I am sure the solution is much simple than this.

I don't want to use something like sleep that stops execution. In short its just replaying a set of coordinates?

Also I plan to do this for many other input methods, so I am wondering if there should be a more general approach.

Any ideas?

ArrayList <chronoPointer> points;
int currentTime; //milliseconds
int lagTime = 300; //milliseconds

void setup() { 
  frameRate(60);

  size(400, 400);
  points = new ArrayList<chronoPointer>();
  noCursor();
}

void draw()
{

  background(60);
  smooth();
  fill(color(0, 255, 0));
  rect(mouseX, mouseY, 20, 20); // this is the non-delayed cursor. Just for debugging point of reference.

  currentTime = millis(); //milliseconds
  fill(color(0, 255, 0));
  text("Current Time: " + currentTime + " ms", 20, 20);
  text("Frame Rate: " + int(frameRate), 20, 35);
  text("Added Lag: " + lagTime + " ms", 20, 50);

  fill(color(225, 173, 140));
  turtleCursor(currentTime); //sends current time to the method to draw the delayed cursor.
}

void mouseMoved()
// Storing mouse coordinates and the time of capture in an array custom type
{
  points.add(new chronoPointer(mouseX, mouseY, currentTime));
}

void mousePressed() {

  fill(color(255, 0, 0));

  // For Debugging purposes to see the times for each coordinate.
  for (int i = 0; i < points.size(); i++) {
    println(" #" + i + ": { X: " + points.get(i).getCoords().x + " Y: " + points.get(i).getCoords().y + ", TIME: " + points.get(i).getCoordTime() + " milliseconds}  ");    
    println("\n");
  }  
  println("\n\n");
}

void mouseReleased() {
  fill(color(0, 255, 0));
}


/* My method to draw delayed cursor*/
void turtleCursor(int currentTime) {
  int delay;  
  try {
    for (int i = 0; i< points.size(); i++) {  
      delay = points.get(i).getCoordTime(); // I know this may be wrong. Multiple coodinates, or one set?, will be returned?

      if (delay == currentTime - lagTime) {  //get the time from the object

        points.get(i).getCoords().lerp(points.get(i+1).getCoords().x, points.get(i+1).getCoords().y, 0.0, 0.1); //trying to lerp here to get smooth drawing between two points.
        ellipse(points.get(i).getCoords().x, points.get(i).getCoords().y, 25, 25);
      }
    }
  } 
  catch (Exception e) {
  }
}



// this class stores the pointer x y coordinates and associated time value.
class chronoPointer {

  PVector pointCoordinates;
  int pointTime;

  void init() {
    println("A chronoPointer has been initialized");
  }  

  public chronoPointer(float xCoord, float yCoord, int timeFrame) {
    pointCoordinates = new PVector(xCoord, yCoord);
    pointTime = timeFrame;
  }

  public PVector getCoords() {
    return pointCoordinates;
  }

  public int getCoordTime() {
    return pointTime;
  }
}

Answers

  • _vk_vk
    Answer ✓

    The following code is from Processing's bundled example StoringInput. Are you looking for something like this?

    /**
     * Storing Input. 
     * 
     * Move the mouse across the screen to change the position
     * of the circles. The positions of the mouse are recorded
     * into an array and played back every frame. Between each
     * frame, the newest value are added to the end of each array
     * and the oldest value is deleted. 
     */
    
    int num = 60;
    float mx[] = new float[num];
    float my[] = new float[num];
    
    void setup() {
      size(640, 360);
      noStroke();
      fill(255, 153); 
    }
    
    void draw() {
      background(51); 
    
      // Cycle through the array, using a different entry on each frame. 
      // Using modulo (%) like this is faster than moving all the values over.
      int which = frameCount % num;
      mx[which] = mouseX;
      my[which] = mouseY;
    
      for (int i = 0; i < num; i++) {
        // which+1 is the smallest (the oldest in the array)
        int index = (which+1 + i) % num;
        ellipse(mx[index], my[index], i, i);
      }
    }
    
  • Hi -VK, Sorry for the late reply. Yes and thank you. I actually had previously played with that example code before with no luck. Later, I played with it a bit more and created a much shorter method (so alas it was simpler). Thank you again for getting me to reconsider this bit.

    So here is my much shorter method turned out as follows: I have two screens one with no delay effect on the left and the other with the effect on the right.

    void ghostPointer() {           
      int num = 30; //delay parameter
      int which = frameCount % num;
      int time = millis()/1000;
    
      if (
          mouseX < screenWidth/2 &&
          mouseY < screenHeight/2) {
              mx[which] = mouseX+(screenWidth/2-10);
              my[which] = mouseY;
          } else if (mouseX > screenWidth/2 &&
          mouseY < screenHeight/2) { 
              mx[which] = mouseX;
              my[which] = mouseY;
          }
    
      pushStyle();
      fill(255,0,0);
      ellipse(mx[(which+1 + 0) % num], my[(which+1 + 0) % num], 20, 20);
      popStyle();  
    } // end ghostPointer
    
Sign In or Register to comment.