Mouse over the circles to affect their boundaries. Link to the source files and editor.
let Circles = [];
let inertia = 0.95;
let k = 0.07;
let oldmx;
let oldmy
function setup() {
createCanvas(800, 800);
for(let i = 0; i < 6; i++){
append(Circles, new Circle(400-50*(i+1)));
}
oldmx = mouseX;
oldmy = mouseY;
}
function draw() {
background(0);
for(let i = 0; i < Circles.length; i++){
let c = Circles[i];
c.display();
}
oldmx = mouseX;
oldmy = mouseY;
}
class Circle {
constructor(r) {
this.points = [];
let limit = 40;
let theta = 2*PI/limit;
for(let i = 0; i < limit; i++){
this.points[i] = new Point(r,theta*i);
}
this.c = color(random(255),random(255),random(255));
}
display(){
noStroke();
fill(this.c);
beginShape();
for(let i = 0; i < this.points.length; i++){
let p = this.points[i];
curveVertex(p.pt.x,p.pt.y);
p.update();
}
let p = this.points[0];
curveVertex(p.pt.x,p.pt.y);
p = this.points[1];
curveVertex(p.pt.x,p.pt.y);
p = this.points[2];
curveVertex(p.pt.x,p.pt.y);
endShape();
}
}
class Point {
constructor(r,theta) {
this.goal = r
this.cr = r;
let x = width/2 + r * cos(theta);
let y = height/2 + r * sin(theta);
this.pt = createVector(x,y);
this.opt = createVector(x,y);
this.rp = 0;
this.th = theta;
}
update(){
let distance = dist(this.opt.x,this.opt.y,mouseX,mouseY);
let newr = this.goal;
if(distance < this.goal/4){
let d1 = dist(oldmx,oldmy,width/2,height/2);
let d2 = dist(mouseX,mouseY,width/2,height/2);
if(d1 < d2){
newr = this.goal + distance;
}else{
newr = this.goal - distance;
}
}
let curr = newr;
if(dist(oldmx,oldmy,mouseX,mouseY) < 2){
curr = this.goal;
}
let r1 = -1 * this.cr + curr;
this.rp = this.rp * inertia + r1*k ;
this.cr += this.rp;
let x = width/2 + this.cr * cos(this.th);
let y = height/2 + this.cr * sin(this.th);
this.pt = createVector(x,y);
}
}