creating circular drop-shadows with processing

Here is an example of a simple way to do circular drop-shadows in Processing.


screenshot of drop-shadow maker

You can view the interactive demo here.

Read more for the source code.

/* ================================================================================
 *          file:  simple_shadow_one.pde
 *   description:  A simple circular shadow with controls
 *  dependencies:  controlP5 - http://www.sojamo.de/controlP5/ (Andreas Schlegel)
 *        author:  Nate Murray, <nate@natemurray.com>
 *       version:  0.1
 *       created:  02/17/08 14:37:55 PST
 * =============================================================================== */
 
import controlP5.*;
ControlP5 controlP5;
 
ShadowBall b;
boolean showBall = true;
 
void setup() {
  size(400, 400);  
  smooth();
  noStroke();
 
  // setu up our initial controls
  controlP5 = new ControlP5(this);
  controlP5.addSlider("diameter",30,300,180,30,height-30,100,10).setId(1);
  controlP5.addSlider("steps",1,500,60,30,height-45,100,10).setId(2);
  controlP5.addSlider("alpha",1,20,7,30,height-60,100,10).setId(3);
  controlP5.addSlider("distance",0,150,0,30,height-75,100,10).setId(4);
  controlP5.addKnob("angle",0,360,90,width-110,height-70,40).setId(5);
 
  // this control sets the showBall variable directly
  // for some reason it doesn't work in an embedded applet though.
  // controlP5.addToggle("showBall",true,width-50,height-50,20,20);
 
  b = new ShadowBall(width/2, height/2, 180);
  // b.shadowColor = #E6FF00; // change this if you want a different color
}
 
void draw() {
  background(53);
  b.draw();
}
 
// Our main controller for the controlP5 events
void controlEvent(ControlEvent theEvent) {
  switch(theEvent.controller().id()) {
    case(1):
      b.shadowDiameter = (float)(theEvent.controller().value());
      break;
    case(2):
      b.shadowSteps = (int)(theEvent.controller().value());
      break;  
    case(3):
      b.alphaStep = (int)(theEvent.controller().value());
      break;  
    case(4):
      b.shadowDistance = (float)(theEvent.controller().value());
      break;  
    case(5):
      b.shadowAngle = (float)(theEvent.controller().value());
      break;  
  }
}
 
// A basic ball class to track the main ellipse
class Ball {
  float x, y;
  float diameter;
 
  Ball(float xin, float yin, float din) {
    x = xin;
    y = yin;
    diameter = din;
  } 
 
  void draw() {
    fill(255);
    ellipse(x, y, diameter, diameter);
  }
 
}
 
class ShadowBall extends Ball {
  int shadowSteps;
  float shadowDiameter;
  float shadowDistance;
  float shadowAngle;
  color shadowColor;
  int alphaStep;
 
  // A simple ball with some default values
  ShadowBall(float xin, float yin, float din) {
    super(xin, yin, din);
    shadowDiameter = din * 1.2;
    shadowSteps = 60;
    shadowDistance = 0;
    shadowAngle = 90;
    alphaStep = 7;
    shadowColor = color(0, 0, 0);
  } 
 
  ShadowBall(float xin, float yin, float din, float sdin, int sstepsin, 
         float sdistin, float sanglein, int astepin) {
    super(xin, yin, din);
    shadowDiameter = sdin;
    shadowSteps = sstepsin;
    shadowDistance = sdistin;
    shadowAngle = sanglein;
    alphaStep = astepin;
    shadowColor = color(0, 0, 0);
  } 
 
  void draw() {
    drawShadow();
 
    // NOTE if take this out if you are going to reuse this class. This is just
    // here to show the shadow alone.
    if(showBall==true) {
      super.draw();
    }
  }
 
  // Draw the shadow
  void drawShadow() {
    float new_di = shadowDiameter;
    float stepSize = shadowDiameter / shadowSteps;
 
    // for each shadowStep we want to draw...
    for (int i = shadowSteps; i > 0; i--) {
      // create a new color for this ring based on the shadowColor
      color col = color(red(shadowColor), 
                      green(shadowColor),
                       blue(shadowColor), alphaStep);
      fill(col);
 
      // translate our origin to be the center of the circle. Rotate it by the
      // angle and then draw our shadow.
      pushMatrix();
      translate(x, y);
      rotate(radians(shadowAngle));
      float the_x = shadowDistance;
      float the_y = shadowDistance;
      ellipse(the_x, the_y, stepSize*i, stepSize*i);
      popMatrix();
    }
 
  }
 
}
Share:
  • del.icio.us
  • Reddit
  • Technorati
  • Twitter
  • Facebook
  • Google Bookmarks
  • HackerNews
  • PDF
  • RSS
This entry was posted in processing and tagged . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.