Falling Snow with Processing.js

[processing] // Multitouch Sparks // Adrian Park // 2012 ArrayList mouseTrail; int prevX; int prevY; int ranX; int ranY; int update = 0; // if multitouch events are fired, this is set to true boolean useMultiTouch = false; void setup() { size( 655 , 630 ); background( 7,45,119 ); smooth(); mouseTrail = new ArrayList(); } void draw() { background( 7,45,119 ); if( ranX != prevX || ranY != prevY ) { // create a spark if the mouse is moving Disc newDisc = new Disc( ranX, ranY ); mouseTrail.add( newDisc ); prevX = ranX; prevY = ranY; } if(update > 5) { update = 0; ranX = random(0,655); ranY = random(0,5); } else { update += 1; } updateDiscs(); } // instructs each spark to draw itself and removes extinguished sparks void updateDiscs() { for( int i = mouseTrail.size() - 1; i > 0; i-- ) { Disc d = (Disc) mouseTrail.get(i); if( !d.isAlive ) { mouseTrail.remove(i); } d.render(); } } class Disc{ int discRadius; int minRadius = 2; int maxRadius = 10; float discAlpha = 255.0; float alphaIncrement = 0.2; float xPos; float yPos; float xVel; float yVel; float friction = 0.98; float gravity = 0.05; int maxStartingVelocity = 2; // colour library color[] colours = new color[3]; color c1 = color(255, 255, 255); color c2 = color(250, 250, 255); color c3 = color(240, 240, 255); color c4 = color(230, 230, 255); color c5 = color(220, 220, 255); color c6 = color(210, 210, 255); int renderColourIndex; color renderColour; // false when alpha <= 0 boolean isAlive = true; Disc( int x, int y ) { discRadius = round( random( minRadius, maxRadius ) ); PVector vector = getRandomVector(); xVel = vector.x; yVel = vector.y; xPos = x; yPos = y; colours[0] = c1; colours[1] = c2; colours[2] = c3; colours[2] = c4; colours[2] = c5; colours[2] = c6; renderColourIndex = round( random(0, colours.length-1 ) ); } // draw the spark to screen void render() { if( isAlive ) { renderColour = getColour(); fill( renderColour ); noStroke(); ellipse( xPos, yPos, discRadius*2, discRadius*2 ); // update properties discAlpha -= alphaIncrement; xPos += xVel; yPos += yVel; xVel = xVel * friction; yVel = (yVel * friction) + gravity; if( discAlpha <= 0 ) { isAlive = false; } } } // randomly chooses a colour from the colour library color getColour() { color randomColour = colours[ renderColourIndex ]; color newColour = color( red(randomColour), green(randomColour), blue(randomColour), discAlpha ); return newColour; } // calculate a random direction and speed for the spark PVector getRandomVector() { float angle = random(0,1) * PI; float velocity = random( 0, maxStartingVelocity ); float x = cos(angle) * velocity; float y = sin(angle) * velocity; PVector vector = new PVector( x, y ); return vector; } } [/processing]
// Adapted from Multitouch Sparks
// Adrian Park <http://www.adrianpark.com>
// 2012

ArrayList mouseTrail;

int prevX;
int prevY;
int ranX;
int ranY;
int update = 0;

// if multitouch events are fired, this is set to true
boolean useMultiTouch = false;

void setup() {
  size( 655 , 630 );
  background( 7,45,119 );
  smooth();
  mouseTrail = new ArrayList();
}

void draw() {
  background( 7,45,119 );

    if( ranX != prevX || ranY != prevY ) {
      // create a spark if the mouse is moving
      Disc newDisc = new Disc( ranX, ranY );
      mouseTrail.add( newDisc );
   
    prevX = ranX;
    prevY = ranY;
    }
  if(update > 5) {
    update = 0;
    ranX = random(0,655);
    ranY = random(0,5);
  } else {
    update += 1;
  } 
  updateDiscs();
}

// instructs each spark to draw itself and removes extinguished sparks
void updateDiscs() {
 
  for( int i = mouseTrail.size() - 1; i > 0; i-- ) {
    Disc d = (Disc) mouseTrail.get(i);
   
    if( !d.isAlive ) {
      mouseTrail.remove(i);
    }
    d.render();
  }
}

class Disc{
  int discRadius;
  int minRadius = 2;
  int maxRadius = 10;
  float discAlpha = 255.0;
  float alphaIncrement = 0.2;
  float xPos;
  float yPos;
  float xVel;
  float yVel;
  float friction = 0.98;
  float gravity = 0.05;
  int maxStartingVelocity = 2;
 
  // colour library
  color[] colours = new color[3];
  color c1 = color(255, 255, 255);
  color c2 = color(250, 250, 255);
  color c3 = color(240, 240, 255);
  color c4 = color(230, 230, 255);
  color c5 = color(220, 220, 255);
  color c6 = color(210, 210, 255);
 
  int renderColourIndex;
  color renderColour;
 
  // false when alpha <= 0
  boolean isAlive = true;
 
  Disc( int x, int y ) {
   
    discRadius = round( random( minRadius, maxRadius ) );
   
    PVector vector = getRandomVector();
    xVel = vector.x;
    yVel = vector.y;
   
    xPos = x;
    yPos = y;
   
    colours[0] = c1;
    colours[1] = c2;
    colours[2] = c3;
    colours[2] = c4;
    colours[2] = c5;
    colours[2] = c6;
   
    renderColourIndex = round( random(0, colours.length-1 ) );
  }
 
  // draw the spark to screen
  void render() {
   
    if( isAlive ) {
      renderColour = getColour();
     
      fill( renderColour );
      noStroke();
     
      ellipse( xPos, yPos, discRadius*2, discRadius*2 );
     
      // update properties
      discAlpha -= alphaIncrement;
      xPos += xVel;
      yPos += yVel;
     
      xVel = xVel * friction;
      yVel = (yVel * friction) + gravity;
     
      if( discAlpha <= 0 ) {
        isAlive = false;
      }
    }
  }
 
  // randomly chooses a colour from the colour library
  color getColour() {
    color randomColour = colours[ renderColourIndex ];
    color newColour = color( red(randomColour), green(randomColour), blue(randomColour), discAlpha );
    return newColour;
  }
 
  // calculate a random direction and speed for the spark
  PVector getRandomVector() {
    float angle = random(0,1) * PI;
    float velocity = random( 0, maxStartingVelocity );
    float x = cos(angle) * velocity;
    float y = sin(angle) * velocity;
    PVector vector = new PVector( x, y );
    return vector;
  }
}

Read More