Daily Creative Coding

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

スウィープすると消える円

/**
 * sweep bubbles
 * 
 * @author aadebdeb
 * @date 2017/03/15
 */

var easingVariables;
var circles;

function setup() {
  createCanvas(windowWidth, windowHeight);
  frameRate(30);
  easingVariables = [];
  circles = [];
  for (var i = 0; i < 500; i++) {
    circles.push(new Circle());
  }
}

function draw() {
  background(235, 238, 232);
  var mouse = createVector(mouseX, mouseY);
  for (var i = 0; i < circles.length; i++) {
    var circle = circles[i];
    circle.render();
    circle.update(mouse);
  }

  updateEasingVariables();
}

function updateEasingVariables() {
  for (var i = 0; i < easingVariables.length; i++) {
    easingVariables[i].update();
  }
}

function isOverlapping(circle) {
  for (var i = 0; i < circles.length; i++) {
    var other = circles[i];
    if (circle === other) {
      continue;
    }
    var d = circle.loc.dist(other.loc);
    if (d < circle.maxRadius + other.maxRadius) {
      return true;
    }
  }
  return false;
}


function EasingVariable() {
  this.value = 0;
  this.step = 0.08;
  this.isIncreasing = true;
  this.isDecreasing = false;
  easingVariables.push(this);
}

EasingVariable.prototype = {
  update: function() {
    if (this.isIncreasing) {
      this.value += this.step;
      if (this.value >= 1) {
        this.value = 1;
        this.isIncreasing = false;
      }
    }
    if (this.isDecreasing) {
      this.value -= this.step;
      if (this.value <= 0) {
        this.value = 0;
        this.isDecreasing = false;
      }
    }
  },
  
  startIncrement: function() {
    this.isIncreasing = true;
    this.isDecreasing = false;
  },
  
  startDecrement: function() {
    this.isIncreasing = false;
    this.isDecreasing = true;
  }
}

function Circle() {
  this.reset();
  this.ev = new EasingVariable();
}

Circle.prototype = {
  reset: function() {
    this.loc = createVector(random(windowWidth), random(windowHeight));
    this.maxRadius = random(10, 30);
    if (isOverlapping(this)) {
      this.reset();
    }
    this.c = lerpColor(color(178, 174, 178, 220), color(201, 199, 197, 220), map(sin(frameCount * 0.04), -1, 1, 0, 1));
  },
  
  getRadius: function() {
    var v = this.ev.value;
    return map(v, 0, 1, 0, this.maxRadius);
  },
  
  render: function() {
    var r = this.getRadius();
    noStroke();
    fill(red(this.c), green(this.c), blue(this.c), 100);
    ellipse(this.loc.x, this.loc.y, r * 2 * 1.1, r * 2 * 1.1);
    fill(this.c);
    ellipse(this.loc.x, this.loc.y, r * 2, r * 2);
  },
  
  update: function(mouse) {
    var d = this.loc.dist(mouse);
    if (!this.ev.isDecreasing && d  < this.getRadius() * 4) {
      this.ev.startDecrement();
    }
    if (!this.ev.isIncreasing && !this.ev.isDecreasing && this.ev.value == 0) {
      this.reset();
      this.ev.startIncrement();
    }
  }
}
f:id:aa_debdeb:20170314213007j:plain