xxxxxxxxxx
176
function preload() {
groteskFont = loadFont('https://cdn.glitch.com/5dd99b18-3ebb-45c5-90fb-b4b67dc2e128%2Fgrotesk.otf?v=1580943594863sk.otf');
}
let animationIndex;
let textPoints;
let followPoints;
let time;
function setup() {
createCanvas(500, 500);
time = 0;
animationIndex = 0;
followPoints = [];
textPoints = [];
let fontDetail = 0.5;
let fontSize = 40;
textPoints.push(createPointText(' 1 ', 0, 0, fontSize, fontDetail, 0));
textPoints.push(createPointText(' 2 ', 0, 0, fontSize, fontDetail, 0));
textPoints.push(createPointText(' 3 ', 0, 0, fontSize, 1, 0));
textPoints.push(createPointText(' S ', 0, 0, fontSize, fontDetail, 0));
textPoints.push(createPointText(' T ', 0, 0, fontSize, fontDetail, 0));
textPoints.push(createPointText(' 6 ', 0, 0, fontSize, fontDetail, 0));
textPoints.push(createPointText(' 7 ', 0, 0, fontSize, fontDetail, 0));
textPoints.push(createPointText(' 8 ', 0, 0, fontSize, fontDetail, 0));
textPoints.push(createPointText(' 9 ', 0, 0, fontSize, fontDetail, 0));
//figure out which text has the most # of points
let maxPoints = 0;
textPoints.forEach(point => {
maxPoints = max(maxPoints, point.length);
});
// Create our Follow Points
for (let i = 0; i < maxPoints; i++) {
let point = new Follow(random(0, width), random(0, height));
followPoints.push(point);
}
}
function draw() {
colorMode(RGB, 255);
background(0, 0, 0, 20);
noStroke();
time += 0.01;
followPoints.forEach((point, index) => {
// textPoints at the current animation index may have fewer
// points than the total # of follow points.
// if our current textPoints[animationIndex].length -1 we have already drawn
// every point for that text, so we return and skip setting the
// point's position and drawing it.
if(index > textPoints[animationIndex].length - 1) {
return;
}
//Notice this is a nested array!
let textPoint = textPoints[animationIndex][index];
/////////
//if you want to modify the position of the text points
// in your animation do it here with textPoint
point.setPos(textPoint.x, textPoint.y);
point.update();
point.draw((x, y) => {
if(animationIndex === 0) {
ellipse(x, y, 25, 25);
}
//////////////////////////////////
// UNCOMMENT to see some exammples
// else if(animationIndex === 1) {
// let circlePos = layoutCircle(5+osc(), 40*osc(), index % (5+osc()), 1,1, time, time);
// line(x, y, x+circlePos.x, y+circlePos.y);
// } else if(animationIndex === 2) {
// let circlePos = layoutCircle(3, 250*osc(), index, 1,1, time, time);
// circlePos.x += width / 2
// circlePos.y += height / 2
// line(x, y, circlePos.x, circlePos.y);
// } else if (animationIndex === 3) {
// noFill();
// let circlePos = layoutCircle(textPoints[3].length, 200, index, 1,1, 0, 0);
// let circlePos2 = layoutCircle(textPoints[3].length, 300, index, 1,1, time, time);
// circlePos.x += width/2;
// circlePos.y += height/2;
// circlePos2.x += width/2;
// circlePos2.y += height/2;
// bezier(x, y, x, y, circlePos2.x, circlePos2.y, circlePos.x, circlePos.y);
// } else if (animationIndex === 4) {
// bezier(x, y, x, y, mouseX, mouseX, mouseX, mouseY);
// }
else {
rect(x, y, 25, 25);
}
});
});
}
// returns an array of text points with an x and y for the given text
function createPointText(text, x, y, fontSize, sampleFactor, simplifyThreshold) {
let textPoints = groteskFont.textToPoints(text, x, y, fontSize, {
sampleFactor: sampleFactor,
simplifyThreshold: simplifyThreshold
});
let bounds = groteskFont.textBounds(text, x, y, fontSize);
//scale each letter to fit the screen
textPoints.forEach(letter => {
letter.x = letter.x * width / bounds.w;
letter.y = letter.y * (height - 100) / bounds.h + height - 60;
});
return textPoints;
}
// incriments the animaiton index
function mousePressed() {
animationIndex += 1;
animationIndex = animationIndex % 9;
}
// Handels interpolating a point towards the a give position using setPos.
// requires: update() to be called every frame and a function for drawing
// to be passed into draw().
class Follow {
constructor(x, y) {
this.currPos = createVector(x, y);
this.finalPos = createVector(0, 0);
this.speed = random(0.1, .2);
}
setPos(x, y) {
this.finalPos.set(x, y);
}
//interpolates the currPos to the finalPos
update() {
this.currPos = p5.Vector.lerp(this.currPos, this.finalPos, this.speed);
}
draw(shape) {
shape(this.currPos.x, this.currPos.y);
}
}
////////////////////////////////////////////////////////
//Helper Functions you could use
// Creates an osscilator that transitions between 0 an 1 a the given scale
function osc(scale, phase = 0) {
if (!scale) {
scale = 1;
}
return abs(sin(frameCount * 0.01 * scale + phase));
}
function layoutCircle(count, scale, index, xOSScale=1, yOSScale=1, xOSOffset=1, yOSOffset =1) {
let inc = map(index, 0, count, 0, TWO_PI);
let x = sin(inc * xOSScale + xOSOffset) * scale;
let y = cos(inc * yOSScale + yOSOffset) * scale;
return ({x, y});
}
function layoutGrid(count, cols, rows, scale, index) {
let x = ((index + 1) % rows) * scale;
let y = ceil(((index + 1) / (count)) * cols) * scale;
x -= scale * rows / 2 - scale / 2;
y -= scale * cols / 2 + scale / 2;
return ({x, y});
}