読者です 読者をやめる 読者になる 読者になる

Daily Creative Coding

元「30 min. Processing」。毎日、Creative Codingします。

キラキラする円

/**
* illuminated circles
*
* @author aa_debdeb
* @date 2016/12/02
*/

ArrayList<Circle> circles;

void setup(){
  size(640, 640);
  noStroke();
  colorMode(HSB, 360, 100, 100);
  circles = new ArrayList<Circle>();
  for(int i = 0; i < 10000; i++){
    float radius = random(1, 60);
    PVector loc = new PVector(random(radius, width - radius), random(radius, height - radius));
    boolean isOverlapped = false;
    for(Circle c: circles){
      if(PVector.dist(loc, c.loc) < radius + c.radius){
        isOverlapped = true;
        break;
      }
    }
    if(!isOverlapped){
      circles.add(new Circle(loc, radius));
    }
  }
}

void draw(){
  background(0, 0, 0);
  for(Circle c: circles){
    c.display();
    c.update();
  }
}

class Circle {
  
  PVector loc;
  float hue;
  float radius;
  boolean isAnimating;
  int startCount, duration;
  
  Circle(PVector _loc, float _radius){
    loc = _loc;
    radius = _radius;
    hue = random(360);
    isAnimating = false;
  }
  
  void display(){
    if(isAnimating){
      float h = hue + map(sin(float(frameCount - startCount) / duration * TWO_PI), -1, 1, -360, 360);
      if(h < 0) h += 360;
      if(h >= 360) h -= 360;
      fill(h, 100, 100);
    } else {
      fill(hue, 100, 100);
    }
    ellipse(loc.x, loc.y, radius * 2, radius * 2); 
  }
  
  void update(){
    PVector mouse = new PVector(mouseX, mouseY);
    if(isAnimating){
      if(frameCount >= startCount + duration){
        isAnimating = false;
      }
    } else if(PVector.dist(loc, mouse) < radius){
      isAnimating = true;
      startCount = frameCount;
      duration = int(random(200, 1000));    
    }
  }
}
f:id:aa_debdeb:20161126085600j:plain