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.