96 lines
2.6 KiB
JavaScript
96 lines
2.6 KiB
JavaScript
let options = {
|
|
sides: 7,
|
|
period: 20,
|
|
skip: 3,
|
|
pointNumber: 12,
|
|
fr: 60,
|
|
addLineFolder() {
|
|
const newFolder = gui.addFolder(
|
|
"Line "
|
|
+ (parseInt((lineFolders[lineFolders.length - 1] || {name: "0"}).name.replace(/[^\d]/g, '')) + 1)
|
|
);
|
|
const newFolderOptions = {
|
|
destroy() {
|
|
newFolder.getRoot().removeFolder(newFolder);
|
|
lineFolders.splice(lineFolders.indexOf(newFolder), 1);
|
|
},
|
|
offset: 0
|
|
}
|
|
newFolder.add(newFolderOptions, "destroy");
|
|
newFolder.add(newFolderOptions, "offset", 0).step(1);
|
|
newFolder.options = newFolderOptions;
|
|
lineFolders.push(newFolder);
|
|
}
|
|
}
|
|
|
|
let gui;
|
|
|
|
const lineFolders = []
|
|
|
|
function setup() {
|
|
createCanvas(500, 500);
|
|
frameRate(options.fr);
|
|
gui = new dat.GUI();
|
|
gui.add(options, "sides", 0, 25).step(1);
|
|
gui.add(options, "period", 0);
|
|
gui.add(options, "skip", 0).step(1);
|
|
gui.add(options, "pointNumber", 0, 50).step(1);
|
|
gui.add(options, "addLineFolder");
|
|
}
|
|
|
|
function draw() {
|
|
const time = frameCount / options.fr / options.period;
|
|
clear();
|
|
|
|
let points = [];
|
|
|
|
for (let i = 0; i < options.pointNumber; i++) {
|
|
const pathLocation = path(time + (i/options.pointNumber));
|
|
points.push(pathLocation);
|
|
}
|
|
|
|
for (const point of points) {
|
|
const scaledPoint = scalePoint(point);
|
|
for (const lineFolder of lineFolders) {
|
|
const folderPoint = scalePoint(points[(points.indexOf(point) + lineFolder.options.offset) % points.length]);
|
|
line(scaledPoint.x, scaledPoint.y, folderPoint.x, folderPoint.y);
|
|
}
|
|
ellipse(scaledPoint.x, scaledPoint.y, 5, 5);
|
|
}
|
|
}
|
|
|
|
function path(location) {
|
|
const index = Math.floor(location * options.sides);
|
|
const nearestLoc = index * options.skip / options.sides;
|
|
const skipLoc = (index * options.skip + options.skip) / options.sides;
|
|
const nearestRadians = TAU * nearestLoc;
|
|
const skipRadians = TAU * skipLoc;
|
|
|
|
const point1 = {
|
|
x: Math.cos(nearestRadians),
|
|
y: Math.sin(nearestRadians)
|
|
};
|
|
|
|
const point2 = {
|
|
x: Math.cos(skipRadians),
|
|
y: Math.sin(skipRadians)
|
|
}
|
|
|
|
const travel = cosstep((location * options.sides) % 1);
|
|
|
|
return {
|
|
x: lerp(point1.x, point2.x, travel),
|
|
y: lerp(point1.y, point2.y, travel)
|
|
};
|
|
}
|
|
|
|
function cosstep(x) {
|
|
return (-Math.cos(x * PI)+1)/2
|
|
}
|
|
|
|
function scalePoint(point) {
|
|
return {
|
|
x: point.x * width / 2 + width / 2,
|
|
y: point.y * height / 2 + height / 2
|
|
}
|
|
} |