Jelly Blobs, Easing and Elastic

Download this episode

Download Video

Description

See easing/elastics sketch in action 

Now that we can render elements to the stage, we expand our sketches to include mouse interaction. In this sketch, we create a Jelly Blob effect by nesting multiple circles with individual elastic settings to constantly follow the mouse or pointer position on screen. We also introduce the core easing algorithm and explain how it works.

To follow along in Visual Studio, please download the Processing Sketchbook projection.

The finished sketch for this lesson can be found below:

int totalBlobs = 10;
Blob[] blobs = new Blob[totalBlobs];
int width, height;
color strokeColor = color(255, 0, 0);
color fillColor = color(255, 255, 255);
float targetX, targetY;
 
void setup() {
    width = 500;
    height = 550;
    targetX = width / 2;
    targetY = height / 2;
    size(width, height);
    noStroke();
    smooth();
    background(0);
    for (int i = 0; i < totalBlobs; i++) {
        Blob blob = new Blob();
        blob.x = random(width);
        blob.y = random(height);
        blob.easingX = .02 + random(.10);
        blob.easingY = .02 + random(.10);
        blob.strokeSize = 100 + random(160.0);
        blob.fillSize = blob.strokeSize - 20.0;
        blobs[i] = blob;
    }
};
 
void draw() {
    background(0);
    fill(strokeColor);
    for (int i = 0; i < totalBlobs; i++) {
        blobs[i].springToward(targetX, targetY);
        blobs[i].renderStroke();
    }
    fill(fillColor);
    for (int i = 0; i < totalBlobs; i++) {
        blobs[i].renderFill();
    }
}
 
void pointerMove(TouchEvent e){
    targetX = e.offsetX;
    targetY = e.offsetY;
}
 
class Blob{
  float x = 0.0;
  float y = 0.0;
  float vx = 0.0;
  float vy = 0.0;
  float easingX = 0.0;
  float easingY = 0.0;
  float strokeSize = 180.0;
  float fillSize = 160.0;
 
  void renderStroke() {
      ellipse(this.x, this.y, this.strokeSize, this.strokeSize);
  }
 
   void renderFill() {
      ellipse(this.x, this.y, this.fillSize, this.fillSize);
  }
 
  void springToward(float _x, float _y) {
      this.vx += (_x - this.x) * this.easingX;
      this.vy += (_y - this.y) * this.easingY;
      this.vx *= .92;
      this.vy *= .90;
      this.x += this.vx;
      this.y += this.vy;
  }
}

Embed

Format

Available formats for this video:

Actual format may change based on video formats available and browser capability.

    The Discussion

    • User profile image
      QuickC

      Is there a trivial way to make the blobs small if they are separate from the blob, but then combine to form one blob equal to the area of the blobs that have reached "near" target?

    • User profile image
      rbarraza

      Hmm, this is a great thing to explore and mess around with. Off the top of my head-

      Since the Blobs are centering around the mouse position, I would calculate the distance of each blob [  Math.sqrt( (mouse.x - blob.x)*(mouse.x - blob.x) + (mouse.y - blob.y)*(mouse.y - blob.y) ) ] and use that scale the fillSize ( which is currently hard coded to 160, with the stroke aways being 20 more ).

      So if any given ball is zero pixels away from the Pointer (it's right at the middle), it is at full scale ( 1.0*160.0 ) but as the distance increases, that scale goes down ( with some lower limit as your minimum acceptable value ).

      That's what I would try first, but I'm sure there are other ways of doing it. Let me know if you try it out and what works for you! 

    • User profile image
      dharmatech

      Here's a port of the code to C#/WPF.

    • User profile image
      Nicolas Carlo

      Loving your videos. Using them as a refresher. Just a pointer, width and height are system variables in Processing that are set by values passed to size() function. It is better to avoid naming your variables width and height so you leave the system variables alone.

    Comments closed

    Comments have been closed since this content was published more than 30 days ago, but if you'd like to send us feedback you can Contact Us.