My first Reactickle for today was KeyboardSpringyCircles, which can be seen at 2:31 on the video that Wendy shot:
I started by duplicating KeyboardScalingCircleGrid, then creating a new SpringyCircle object:
function SpringyCircle(){ //SpringyCircle object
var circleMinRadius = 100;
var circleMaxRadius = 200;
this.colour = color(random(100),50,100,50);; //random hue, saturation 50%, brightness 100%, alpha 50%
this.radius = random(circleMinRadius,circleMaxRadius);
this.position = createVector(random(windowWidth)/windowWidth,random(windowHeight)/windowHeight);
// Spring simulation from https://p5js.org/examples/simulate-spring.html
// Spring simulation constants
this.M = 0.8; // Mass
this.K = 0.2; // Spring constant
this.D = 0.92; // Damping
this.R = this.position.y; // Rest position
// Spring simulation variables
//this.ps = R, // Position, not needed as we have this.position.y
this.vs = 0.0, // Velocity
this.as = 0, // Acceleration
this.f = 0; // Force
this.display = function(){
this.spring();
var translatedX = this.position.x * windowWidth;
var translatedY = this.position.y * windowHeight;
fill(this.colour);
ellipse(translatedX, translatedY, this.radius, this.radius);
}
this.spring = function(){
// Update the spring position
this.f = -this.K * ( this.position.y - this.R ); // f=-ky
this.as = this.f / this.M; // Set the acceleration, f=ma == a=f/m
this.vs = this.D * (this.vs + this.as); // Set the velocity
this.position.y = this.position.y + this.vs; // Updated position
if (abs(this.vs) < 0.1) {
this.vs = 0.0;
}
}
this.moveSpring = function(){ //move the position of the spring a bit
this.position.y += 0.2; //move a 5th of the screen down
}
}
As noted in the source code comments, the spring simulation was based on the spring p5.js example. Once I had the circles randomly generating their position, colour and radius, I had to add the interaction – springing if a key was pressed within their area:
function keyTyped(){
var lowerCaseKey = key.toLowerCase(); //key is a system variable via https://p5js.org/reference/#/p5/key, toLowerCase via http://www.w3schools.com/jsref/jsref_tolowercase.asp
if(allTheKeys.includes(lowerCaseKey)){
//if the key is a valid one, circles nearby should react
var positionOfKey = getCanvasPositionFromKey(lowerCaseKey);
var positionOfKeyInPixels = createVector(positionOfKey.x * windowWidth, positionOfKey.y * windowHeight);
for (var i = 0; i < springyCircles.length; i++) {
//for all the springyCircles
var positionOfCircleInPixels = createVector(springyCircles[i].position.x * windowWidth, springyCircles[i].position.y * windowHeight);
var radiusOfCircle = springyCircles[i].radius;
var distanceBetweenKeyAndCircle = dist(positionOfKeyInPixels.x, positionOfKeyInPixels.y, positionOfCircleInPixels.x, positionOfCircleInPixels.y);
if(distanceBetweenKeyAndCircle < radiusOfCircle){
//if the key is under the springy circle, then spring/move it
springyCircles[i].moveSpring();
}
}
}
return false; //https://p5js.org/reference/#/p5/keyTyped preventing default behaviour
}
Try the KeyboardSpringyCircles demo.
I wanted this to work with mouse clicks and touches on mobile, so I quickly created MouseSpringyCircles, which swapped the above keyboard code for a mouse or touch interaction:
function checkIfCirclesShouldSpring(){
for (var i = 0; i < springyCircles.length; i++) {
//for all the springyCircles
var positionOfCircleInPixels = createVector(springyCircles[i].position.x * windowWidth, springyCircles[i].position.y * windowHeight);
var distanceBetweenMouseAndCircle = dist(mouseX, mouseY, positionOfCircleInPixels.x, positionOfCircleInPixels.y); //https://p5js.org/reference/#/p5/dist
if(distanceBetweenMouseAndCircle < (springyCircles[i].radius)){ //this is resulting in a bug - radius/2 works properly, but why isn't radius alone giving the correct interaction?
//if the mouse is under the springy circle, then spring/move it
springyCircles[i].moveSpring();
}
}
}
function touchMoved(){
checkIfCirclesShouldSpring();
return false; //https://p5js.org/reference/#/p5/touchMoved
}
function mouseReleased(){
checkIfCirclesShouldSpring();
}
function keyTyped(){
var lowerCaseKey = key.toLowerCase(); //key is a system variable via https://p5js.org/reference/#/p5/key, toLowerCase via http://www.w3schools.com/jsref/jsref_tolowercase.asp
return false; //https://p5js.org/reference/#/p5/keyTyped preventing default behaviour
}
Try the MouseSpringyCircles demo.
As noted in the source code, there is a bug on selection of circles which I am going to come back to tomorrow.
The last of the three Reactickles that I wanted to port was KeyboardBouncingCircleGrid, which I made by combining KeyboardSpringyCircles with the previously created KeyboardScalingCircleGrid.
Try the KeyboardBouncingCircleGrid demo.