UI Dial With Snaps

Creating a UI element with Processing.js

// UIDial for Processing.js
// F1LT3R @ Hyper-Metrix.com


void setup(){
  size(320,320);
  strokeWeight(4);
  stroke(0);
  strokeWeight(1);
  frameRate(60);  
}

// DIAL AND GRIP
int diameter = 200;
int meassures = 6;
int meassureWeight = 6;
int meassureLength = 10;
int indicatorWeight = 1;
float radMess = radians(360 / meassures);
float radDiv = (radians(360) / meassures) /4;
int dialAngle = radians(90);

// Functional Variables
int radius = diameter / 2;
boolean holding = false;
int i=0;

// SNAPS AND MAGNETISM
int snaps=5;
int snapDist = 30;
int snapDiam = 15;
int snapPos = 0;
int snapStartAng = 90; // The angle at which the snaps (LEDs) start.
int snapRange = 180; // The angular range the snaps cover. 
int snapEase = radians( (snapRange/snaps) / 2 ); // The easing angle factor for TRUE state.
float magPull = 0;
float magFieldFalloff = 1.25;
boolean snapped = false;
int snap = 0;

// TEMPO CONTROL
float BPM = 120;
float MsPB = 60000 / BPM;
float beatStart = millis();
float nextBeat = beatStart + MsPB; 
float pulseWidth = 1 / MsPB; // time in ms to next beat (fraction)
float pulseClock;
float pulse;

// Font
PFont verdana = loadFont("verdana");
textFont(verdana, 20);


// VOID DRAW
void draw(){  
  background(100);    
  
  if (millis() >= nextBeat){  
      beatStart = millis();
      nextBeat = beatStart + MsPB;
  }
        
  translate(width/2, height/2);  
  drawDial();    
  drawSnaps();
}

// DRAW SNAPS
void drawSnaps(){
  snapped=false;
  
  //pushMatrix();
  rotate( radians(snapStartAng) );
  for (i=0; i < snaps; i++){
      // SnapOff Base
      stroke(50,0,0); fill(100,0,0);
      ellipse(0, radius+snapDist, snapDiam, snapDiam);
      // SnapOff Round Light
      noStroke(); fill(150,0,0);
      ellipse(0, radius+snapDist, snapDiam/1.5, snapDiam/1.5);      
      
      // Calculate current Snap Position
      snapPos = radians( snapStartAng+(snapRange/(snaps-1))*i );      
      if (dialAngle >= snapPos-snapEase && dialAngle <= snapPos+snapEase){
          snap = i;
          snapped=true;
                          
          // Magnet & Tempo Calcs.
          magPull = dialAngle - ((snapPos+snapEase));                            
          pulseClock = (1 / MsPB) * (beatStart -millis()) ;  
          pulse = sin( pulseClock * 4);                
          // SnapOn Base
          stroke(0, 50 ,0); fill(0, 155+pulse*50, 0);
          ellipse(0, radius+snapDist, snapDiam, snapDiam);
          // SnapOn Round Light
          noStroke(); fill(0, 255+pulse*100, 0);        
          ellipse(0, radius+snapDist, snapDiam/1.5, snapDiam/1.5);
          // SnapOn Glow
          fill(0, 155+pulse*50, 0, 25);
          ellipse(0, radius+snapDist, snapDiam+10, snapDiam+10);
          fill(0, 155+pulse*50, 0, 50);
          ellipse(0, radius+snapDist, snapDiam+3, snapDiam+3);        
      }                           
         
  rotate( radians (snapRange/(snaps-1)) );
  }
  endShape();
    
}

// DRAW DIAL
void drawDial(){    
    pushMatrix();      
        rotate(dialAngle - (magPull+snapEase));    
        
        // Draw Dial Base
        stroke(0); fill(65);
        ellipse(0, 0, diameter, diameter);

        // Draw Dial Base Highlight
        if (snapped){
          noStroke(); fill(65, 130+pulse*65, 65, 10);
          arc(0, 0, diameter-1, diameter-1, radians(90)-radMess, radians(90)+radMess);    
        }
    
        // Draw Dial Grip
        stroke(50); fill(80);  
        beginShape();
        vertex (10, radius-10); // anchor
        for (i=0; i < meassures; i++){                               
            rotate( -radians ( 360 / meassures ) );      
            vertex (-10, radius-10);
            vertex (-5, radius);
            vertex (5, radius);
            vertex (10, radius-10);                                                                  
        }    
        endShape();

        // Draw Dial Indicator
        stroke(50); fill(200+(pulse*5));  
        beginShape();
          rect(-10, -5, 20, radius+10 );
        endShape();            
    popMatrix();         
}

void mousePressed() {
    holding=true;       
}

void mouseReleased() {
    holding=false;
    if(snapped){ gotSnap(snap, snapped) };
}

void mouseMoved() { 
    if ( holding ){ dialAngle = - atan2( width / 2 - mouseX, height / 2 - mouseY ) + PI }
}




Would love to hear from you if you use this code.