Loading user information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading user information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Jelly Blobs, Easing and Elastic

35 minutes, 47 seconds


Right click “Save as…”

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);
    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() {
    for (int i = 0; i < totalBlobs; i++) {
        blobs[i].springToward(targetX, targetY);
    for (int i = 0; i < totalBlobs; i++) {
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;

Follow the discussion

  • Oops, something didn't work.

    Getting subscription
    Subscribe to this conversation
  • Kyle EppleyQuickC I'm a Parallel Programmer

    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?

  • Rick Barrazarbarraza Form Follows Fiction

    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! 

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

  • Nicolas CarloNicolas 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.

Remove this comment

Remove this thread


Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.