xxxxxxxxxx
279
let b = [];
let font;
let noiseBoolean = true;
let fps = 60;
function preload() {
font = loadFont("JosefinSans-SemiBoldItalic.ttf");
// font = loadFont('JosefinSans-Medium.ttf');
}
function setup() {
createCanvas(600, 550);
background(0); // without it theres a fade from white to black upon starting
// x,y, ,magnitude, circle-radius , originX, originY, initialHeading, color()
textAlign(CENTER);
/*
Doing more than one line:
Array for every line of text, each element is a
line, for each line call the function points with
yeah its obvious by this point
will do later
*/
let points0 = textPoints("INTRO TO", width / 2 - 10, height / 4, 110, 0.1);
setupCircles(points0);
points0 = textPoints(
"INTERACTIVE",
width / 2 - 10,
(height * 2) / 4,
80,
0.15
);
setupCircles(points0);
points0 = textPoints("MEDIA!", width / 2 - 10, (height * 2) / 3, 80, 0.15);
setupCircles(points0);
points0 = textPoints("MADE BY SAEED", width / 2 - 10, height - 40, 32, 0.2);
setupCircles(points0);
}
function setupCircles(points) {
let numberOfCircles = points.length; // number of circles being made is equal to the number of points in the text
for (let i = 0; i < numberOfCircles; i++) {
// for each circle
// make a random x,y position
// make a random magnitude which is within some values
// let the circle-radius be the same for all
// have the originX and originY be set to a point from points, originX = points[i].x etc.
// have the initial heading be random and between 360 and 0 (use degrees)
// have the color be a gradient of the color red, i.e. the values of R (red) range between 40 and 255 and is mapped to i being from 0 to points.length
// stroke boolean is true if i%2 == 0 is true (i.e. when number is even so that half have stroke half dont) I felt this was a cool effect when I made my previous project
let r = random(0, 1);
let maxMag = 5;
let minMag = 2;
let randomX = map(r, 0, 1, 0, width);
let randomY = map(r, 0, 1, 0, height);
let randomMag = map(r, 0, 1, minMag, maxMag);
let circleRadius = 2;
let originX = points[i].x;
let originY = points[i].y;
let initialHeadingRandom = map(r, 0, 1, 0, 360);
colorMode(RGB, 255);
let gradient = map(i, 0, numberOfCircles, 50, 255);
let gradient0 = map(i, 0, numberOfCircles, 255, 50);
let colorGradient = color(gradient0, 0, gradient);
// b[i] = new bounceCircle(randomX, randomY, randomMag, circleRadius, originX, originY, initialHeadingRandom, colorGradient) // insert values here
let circle = new bounceCircle(
randomX,
randomY,
randomMag,
circleRadius,
originX,
originY,
initialHeadingRandom,
colorGradient
); // insert values here
b.push(circle);
}
}
function textPoints(string, x, y, fontSize, sampleF) {
textAlign(CENTER);
let tb = font.textBounds(string, x, y, fontSize);
// get the height and width of the text
let w0 = tb.w;
let h0 = tb.h;
x = x - w0 / 2;
y = y + h0 / 2;
textSize(fontSize);
points = font.textToPoints(string, x, y, fontSize, { sampleFactor: sampleF });
// points is an array
return points;
}
function draw() {
background(0, 20);
push();
// loop through b[] and make an if statement such that when a key is held down all the circles return to the origin, i.e. returnToOrigin method is called and not update(), but at the end of it drawObject is always called
frameRate(fps);
noStroke();
for (let i = 0; i < b.length; i++) {
if (mouseIsPressed) {
b[i].returnOrigin();
} else {
b[i].update();
}
b[i].drawObject();
}
pop();
}
class bounceCircle {
constructor(
posX,
posY,
magnitude,
radius,
originX,
originY,
initialHeading,
objectColor,
strokeTrue
) {
this.posX = posX; // x-position of the circle
this.posY = posY; // y-position of the circle
this.magnitude = magnitude; // magnitude means how much it moves every frame
this.radius = radius; // radius of the circle
this.originX = originX; // the origin-x of the circle (see below for a more detailed explanation)
this.originY = originY; // the origin-y of the circle
this.objectColor = objectColor; // color of the circle when drawn (use a color() object)
this.strokeTrue = strokeTrue; // if true then a stroke is drawn (outline) if false then it is not drawn
angleMode(DEGREES);
this.v0 = createVector(this.posX, this.posY);
this.v0.setHeading(initialHeading);
// this.v0.setHeading(300); to be randomized
this.v0.setMag(this.magnitude);
// set vectors for each side
let leftVector = createVector(0, height / 2);
leftVector.setHeading(180);
let rightVector = createVector(width, height / 2);
rightVector.setHeading(180);
let upVector = createVector(width / 2, 0);
upVector.setHeading(90);
let downVector = createVector(width / 2, height);
downVector.setHeading(90);
this.leftVector = leftVector;
this.rightVector = rightVector;
this.upVector = upVector;
this.downVector = downVector;
}
drawObject() {
push();
fill(this.objectColor);
circle(this.posX, this.posY, this.radius);
pop();
}
returnOrigin() {
// find angle from the v0 to origin
// difference in x from posX to the originX (abs value)
let a = atan2(this.originY - this.posY, this.originX - this.posX);
this.v0.setHeading(a);
// update() until distance less than or equal to magnitude is reached then fix positionxy to originxy and stop updating
let distance = dist(this.posX, this.posY, this.originX, this.originY);
if (distance > this.magnitude) {
this.update();
} else {
// options for some cool effects
// comment out the set heading below
// set this.posX to *= n and/or the same for this.posY
// increase from 0.0001 to a higher value or not
if (noiseBoolean) {
let n = noise(frameCount * 0.00001);
this.posX -= n;
this.posY += n;
}
angleMode(DEGREES);
this.v0.setHeading(map(random(0, 1), 0, 1, 0, 360));
}
}
update() {
angleMode(DEGREES);
this.posX = this.posX + this.v0.x;
this.posY = this.posY + this.v0.y;
// theres a problem where when it hits the corner it decides to go in a straight line into the next corner. Not sure why this happens, I think its to do with the if statements, but its rare enough where debugging isn't worth it (at least by my standards).
// overarching if statement, if false then it goes into other if statements to see which part is false
if (
!(
this.posY < height &&
this.posY > 0 &&
this.posX > 0 &&
this.posX < width
)
) {
if (this.posX > 0 && this.posX < width) {
// top and bottom
if (this.posY < 0) {
// top reflect
this.v0 = p5.Vector.reflect(this.v0, this.upVector);
}
if (this.posY > height) {
//bottom reflect
this.v0 = p5.Vector.reflect(this.v0, this.downVector);
}
} else {
// left and right
if (this.posX <= 0) {
// left reflect
this.v0 = p5.Vector.reflect(this.v0, this.leftVector);
}
if (this.posX >= width) {
// right reflect
this.v0 = p5.Vector.reflect(this.v0, this.rightVector);
}
}
}
// noise for the heading
}
}
// :/
// There is a much better way of doing this without using vectors but I am glad I did use vectors for this anyways. I think it would have been less laggy with the other method.