xxxxxxxxxx
462
let tA1 = 20;
let tB1 = 0;
let tC1 = 0;
let tD1 = 60;
let tA2 = 0;
let tB2 = 0;
let tC2 = 0;
let tD2 = 0;
let t = 0;
let tcos;
let ui;
let customShape;
let densityY,densityX;
let tileY = 9;
let tileX = 9;
let slotSize, canvasY, canvasX;
let mode;
let reverse = 1;
let svg;
let spacing, spacing_CTRL;
let startA_CTRL, startB_CTRL, startC_CTRL, startD_CTRL;
let endA_CTRL, endB_CTRL, endC_CTRL, endD_CTRL;
let startATime_CTRL, startBTime_CTRL, startCTime_CTRL, startDTime_CTRL;
let endATime_CTRL, endBTime_CTRL, endCTime_CTRL, endDTime_CTRL;
let resetStart, resetEnd, stopAnimationStart, stopAnimationEnd;
function setup() {
exportSVG();
borderY = (height - canvasY)/2;
borderX = ( - canvasX)/2;
mode = createSelect();
mode.position(width / 2 - 30 -154, height - 30);
mode.option('squares');
mode.option('circles');
densityY = createSlider(2, 39, 12);
densityY.position((width / 2) - 150 -154, height - 60);
densityY.size(300);
densityX = createSlider(2, 39, 9);
densityX.position((width / 2) - 150 -154, height - 90);
densityX.size(300);
ui = new UI(densityY.value, densityX.value);
ui.slidersA();
ui.slidersB();
ui.slidersATime();
ui.slidersBTime();
// ui.sliderSpacing();
ui.ResetStart();
ui.ResetEnd();
ui.stopAnimationStart();
ui.stopAnimationEnd();
ui.ExportSVG();
}
function draw() {
background(0);
tileY = densityY.value();
tileX = densityX.value();
spacing = 0;
if (tileY > tileX){
canvasY = (height - (height / 3));
slotSize = (canvasY / tileY) - (spacing/(tileY+1));
canvasX = slotSize * tileX;
}else if (tileY < tileX){
canvasX = (height - (height / 3));
slotSize = (canvasX / tileX) - (spacing/(tileX+1));
canvasY = slotSize * tileY;
}else{
canvasY = (height - (height / 3));
slotSize = (canvasY / tileY) - (spacing/(tileY+1));
canvasX = slotSize * tileX;
}
PatternY(canvasY, canvasX, slotSize,spacing);
Time();
}
class UI {
constructor() {
canvasY = (height - (height / 3));
slotSize = canvasY / tileY;
canvasX = slotSize * tileX;
// this.borderX = (width - canvasX) / 2;
this.borderX = ((width - canvasX) / 2) + 200;
this.borderY = (height - canvasY) / 2;
this.x = 0
this.y = 0
this.geometryMode = mode.value();
}
slidersA() {
startA_CTRL = createSlider(-360, 360, 0);
startA_CTRL.position((width - this.borderX) + 90, this.borderY);
startB_CTRL = createSlider(-360, 360, 0);
startB_CTRL.position((width - this.borderX) + 90, this.borderY + 25);
startC_CTRL = createSlider(-360, 360, 0);
startC_CTRL.position((width - this.borderX) + 90, this.borderY + 50);
startD_CTRL = createSlider(-360, 360, 0);
startD_CTRL.position((width - this.borderX) + 90, this.borderY + 75);
}
slidersB() {
endA_CTRL = createSlider(-360, 360, 0);
endA_CTRL.position((width - this.borderX) + 90, (height - this.borderY) - 80);
endB_CTRL = createSlider(-360, 360, 0);
endB_CTRL.position((width - this.borderX) + 90, (height - this.borderY) - 60);
endC_CTRL = createSlider(-360, 360, 0);
endC_CTRL.position((width - this.borderX) + 90, (height - this.borderY) - 40);
endD_CTRL = createSlider(-360, 360, 0);
endD_CTRL.position((width - this.borderX) + 90, (height - this.borderY) - 20);
}
slidersATime() {
startATime_CTRL = createSlider(-0.2, 0.2, 0, 0.1);
startATime_CTRL.position((width - this.borderX) + 230, this.borderY);
startBTime_CTRL = createSlider(-0.2, 0.2, 0 + tcos, 0.1);
startBTime_CTRL.position((width - this.borderX) + 230, this.borderY + 25);
startCTime_CTRL = createSlider(-0.2, 0.2, 0, 0.1);
startCTime_CTRL.position((width - this.borderX) + 230, this.borderY + 50);
startDTime_CTRL = createSlider(-0.2, 0.2, 0, 0.1);
startDTime_CTRL.position((width - this.borderX) + 230, this.borderY + 75);
}
slidersBTime() {
endATime_CTRL = createSlider(-0.2, 0.2, 0, 0.1);
endATime_CTRL.position((width - this.borderX) + 230, (height - this.borderY) - 80);
endBTime_CTRL = createSlider(-0.2, 0.2, 0, 0.1);
endBTime_CTRL.position((width - this.borderX) + 230, (height - this.borderY) - 60);
endCTime_CTRL = createSlider(-0.2, 0.2, 0, 0.1);
endCTime_CTRL.position((width - this.borderX) + 230, (height - this.borderY) - 40);
endDTime_CTRL = createSlider(-0.2, 0.2, 0, 0.1);
endDTime_CTRL.position((width - this.borderX) + 230, (height - this.borderY) - 20);
}
// sliderSpacing(){
// spacing_CTRL = createSlider(0,400,0);
// spacing_CTRL.position((width / 2) - 100, height - 120);
// spacing_CTRL.size(200);
// }
ResetStart() {
resetStart = createButton('reset_position');
resetStart.position((width - this.borderX) + 113, this.borderY + 125);
resetStart.mousePressed(RStart);
}
ResetEnd() {
resetEnd = createButton('reset_position');
resetEnd.position((width - this.borderX) + 113, (height - this.borderY) - 120);
resetEnd.mousePressed(REnd);
}
stopAnimationStart() {
resetStart = createButton('stop_animation');
resetStart.position((width - this.borderX) + 248, this.borderY + 125);
resetStart.mousePressed(AStopStart);
}
stopAnimationEnd() {
resetEnd = createButton('stop_animation');
resetEnd.position((width - this.borderX) + 248, (height - this.borderY) - 120);
resetEnd.mousePressed(AStopEnd);
}
ExportSVG() {
svg = createButton('export svg');
svg.position(width / 2 - 38 -154, this.borderY / 3);
svg.mousePressed(exportSVG);
}
}
class CShape {
constructor(i, j, canvasY, canvasX, slotSize) {
// this.borderX = (width - canvasX) / 2;
this.borderX = (width - canvasX) / 2 -154;
this.borderY = (height - canvasY) / 2;
this.geometryMode = mode.value();
// values from 0 - 360
this.startA = startA_CTRL.value() + tA1;
this.startB = startB_CTRL.value() + tB1;
this.startC = startC_CTRL.value() + tC1;
this.startD = startD_CTRL.value() + tD1;
this.endA = endA_CTRL.value() + tA2;
this.endB = endB_CTRL.value() + tB2;
this.endC = endC_CTRL.value() + tC2;
this.endD = endD_CTRL.value() + tD2;
this.deltaA = this.endA - this.startA;
this.deltaB = this.endB - this.startB;
this.deltaC = this.endC - this.startC;
this.deltaD = this.endD - this.startD;
this.A = (this.startA + (this.deltaA / (tileY - 1)) * i);
this.B = (this.startB + (this.deltaB / (tileY - 1)) * i);
this.C = (this.startC + (this.deltaC / (tileX - 1)) * j);
this.D = (this.startD + (this.deltaD / (tileX - 1)) * j);
//x and y map the 0-360 values and then subtract to complete a turn
if (this.geometryMode == 'circles') {
this.Ax = map(this.A, -45, 45, 0, slotSize, 1) - map(this.A, 135, 225, 0, slotSize, 1) + map(this.A, -135, -225, 0, slotSize, 1) - map(this.A, -315, -360, 0, slotSize / 2, 1) + map(this.A, 315, 360, 0, slotSize / 2, 1);
this.Ay = map(this.A, 45, 135, 0, slotSize, 1) - map(this.A, 225, 315, 0, slotSize, 1) + map(this.A, -45, -135, 0, slotSize, 1) - map(this.A, -225, -315, 0, slotSize, 1);
this.Bx = map(this.B, -45, -135, slotSize, 0, 1) + map(this.B, -225, -315, 0, slotSize, 1) - map(this.B, 45, 135, 0, slotSize, 1) + map(this.B, 225, 315, 0, slotSize, 1);
this.By = map(this.B, -45, 45, 0, slotSize, 1) - map(this.B, 135, 225, 0, slotSize, 1) + map(this.B, -135, -225, 0, slotSize, 1) - map(this.B, -315, -360, 0, slotSize / 2, 1) + map(this.B, 315, 360, 0, slotSize / 2, 1);
this.Cx = map(this.C, -45, 45, slotSize, 0, 1) - map(this.C, 135, 225, slotSize, 0, 1) + map(this.C, -135, -225, slotSize, 0, 1) + map(this.C, -315, -360, 0, slotSize / 2, 1) - map(this.C, 315, 360, 0, slotSize / 2, 1);
this.Cy = map(this.C, -45, -135, slotSize, 0, 1) + map(this.C, -225, -315, 0, slotSize, 1) - map(this.C, 45, 135, 0, slotSize, 1) + map(this.C, 225, 315, 0, slotSize, 1);
this.Dx = map(this.D, -45, -135, 0, slotSize, 1) + map(this.D, -225, -315, slotSize, 0, 1) - map(this.D, 45, 135, slotSize, 0, 1) - map(this.D, 225, 315, 0, slotSize, 1);
this.Dy = map(this.D, -45, 45, slotSize, 0, 1) + map(this.D, 135, 225, 0, slotSize, 1) - map(this.D, -135, -225, 0, slotSize, 1) + map(this.D, -315, -360, 0, slotSize / 2, 1) - map(this.D, 315, 360, 0, slotSize / 2, 1);
} else if (this.geometryMode == 'squares') {
this.Ax = map(this.A, 0, 90, 0, slotSize, 1) - map(this.A, 180, 270, 0, slotSize, 1) + map(this.A, -90, -180, 0, slotSize, 1) - map(this.A, -270, -360, 0, slotSize, 1);
this.Ay = map(this.A, 90, 180, 0, slotSize, 1) - map(this.A, 270, 360, 0, slotSize, 1) + map(this.A, 0, -90, 0, slotSize, 1) - map(this.A, -180, -270, 0, slotSize, 1);
this.Bx = map(this.B, 0, -90, slotSize, 0, 1) + map(this.B, -180, -270, 0, slotSize, 1) - map(this.B, 90, 180, 0, slotSize, 1) + map(this.B, 270, 360, 0, slotSize, 1);
this.By = map(this.B, 0, 90, 0, slotSize, 1) - map(this.B, 180, 270, 0, slotSize, 1) + map(this.B, -90, -180, 0, slotSize, 1) - map(this.B, -270, -360, 0, slotSize, 1);
this.Cx = map(this.C, 0, 90, slotSize, 0, 1) - map(this.C, 180, 270, slotSize, 0, 1) + map(this.C, -90, -180, slotSize, 0, 1) + map(this.C, -270, -360, 0, slotSize, 1);
this.Cy = map(this.C, 0, -90, slotSize, 0, 1) + map(this.C, -180, -270, 0, slotSize, 1) - map(this.C, 90, 180, 0, slotSize, 1) + map(this.C, 270, 360, 0, slotSize, 1);
this.Dx = map(this.D, 0, -90, 0, slotSize, 1) + map(this.D, -180, -270, slotSize, 0, 1) - map(this.D, 90, 180, slotSize, 0, 1) - map(this.D, 270, 360, 0, slotSize, 1);
this.Dy = map(this.D, 0, 90, slotSize, 0, 1) + map(this.D, 180, 270, 0, slotSize, 1) - map(this.D, -90, -180, 0, slotSize, 1) + map(this.D, -270, -360, 0, slotSize, 1);
}
// defines only the control points v3
this.ARx = this.Ax + ((slotSize - this.Ax) * 0.552);
this.ARy = this.Ay;
this.BLx = this.Bx;
this.BLy = this.By - ((this.By) * 0.552);
this.BRx = this.Bx;
this.BRy = this.By + ((slotSize - this.By) * 0.552);
this.CLx = this.Cx + ((slotSize - this.Cx) * 0.552);
this.CLy = this.Cy;
this.CRx = this.Cx - ((this.Cx) * 0.552);
this.CRy = this.Cy;
this.DLx = this.Dx;
this.DLy = this.Dy + ((slotSize - this.Dy) * 0.552);
this.DRx = this.Dx;
this.DRy = this.Dy - ((this.Dy) * 0.552);
this.ALx = this.Ax - ((this.Ax) * 0.552);
this.ALy = this.Ay;
}
geometry() {
if (this.geometryMode == 'circles') {
beginShape();
vertex(this.Ax + this.borderX, this.Ay + this.borderY);
bezierVertex(this.ARx + this.borderX, this.ARy + this.borderY, this.BLx + this.borderX, this.BLy + this.borderY, this.Bx + this.borderX, this.By + this.borderY);
bezierVertex(this.BRx + this.borderX, this.BRy + this.borderY, this.CLx + this.borderX, this.CLy + this.borderY, this.Cx + this.borderX, this.Cy + this.borderY);
bezierVertex(this.CRx + this.borderX, this.CRy + this.borderY, this.DLx + this.borderX, this.DLy + this.borderY, this.Dx + this.borderX, this.Dy + this.borderY);
bezierVertex(this.DRx + this.borderX, this.DRy + this.borderY, this.ALx + this.borderX, this.ALy + this.borderY, this.Ax + this.borderX, this.Ay + this.borderY);
endShape();
} else if (this.geometryMode == 'squares') {
beginShape();
vertex(this.Ax + this.borderX, this.Ay + this.borderY);
vertex(this.Bx + this.borderX, this.By + this.borderY);
vertex(this.Cx + this.borderX, this.Cy + this.borderY);
vertex(this.Dx + this.borderX, this.Dy + this.borderY);
vertex(this.Ax + this.borderX, this.Ay + this.borderY);
endShape();
}
}
}
function PatternY(canvasY, canvasX, slotSize,spacing) {
for (let i = 0; i < tileY; i++) {
push();
translate(0, i * slotSize + ((spacing/tileY) *i));
PatternX(i, canvasY, canvasX, slotSize,spacing);
pop();
}
}
function PatternX(i, canvasY, canvasX, slotSize,spacing) {
for (let j = 0; j < tileX ; j++) {
push();
translate(j * slotSize + ((spacing/tileX)*j), 0);
customShape = new CShape(i, j, canvasY, canvasX, slotSize);
customShape.geometry();
pop();
}
}
function RStart() {
startA_CTRL.value(0);
tA1 = 0;
startB_CTRL.value(0);
tB1 = 0;
startC_CTRL.value(0);
tC1 = 0;
startD_CTRL.value(0);
tD1 = 0;
}
function REnd() {
endA_CTRL.value(0);
tA2 = 0;
endB_CTRL.value(0);
tB2 = 0;
endC_CTRL.value(0);
tC2 = 0;
endD_CTRL.value(0);
tD2 = 0;
}
function AStopStart() {
startATime_CTRL.value(0);
startBTime_CTRL.value(0);
startCTime_CTRL.value(0);
startDTime_CTRL.value(0);
}
function AStopEnd() {
endATime_CTRL.value(0);
endBTime_CTRL.value(0);
endCTime_CTRL.value(0);
endDTime_CTRL.value(0);
}
function Time() {
tA1 += startATime_CTRL.value() * reverse * tileX;
if (tA1 > 360) {
Reverse(-1, startATime_CTRL.value());
tA1 = 360;
} else if (tA1 < -360) {
Reverse(1, startATime_CTRL.value());
tA1 = -360;
} else {
tA1 = tA1;
}
tB1 += startBTime_CTRL.value() * reverse * tileX;
if (tB1 > 360) {
Reverse(-1, startBTime_CTRL.value());
tB1 = 360;
} else if (tB1 < -360) {
Reverse(1, startBTime_CTRL.value());
tB1 = -360;
} else {
tB1 = tB1;
}
tC1 += startCTime_CTRL.value() * reverse * tileY;
if (tC1 > 360) {
Reverse(-1, startCTime_CTRL.value());
tC1 = 360;
} else if (tC1 < -360) {
Reverse(1, startCTime_CTRL.value());
tC1 = -360;
} else {
tC1 = tC1;
}
tD1 += startDTime_CTRL.value() * reverse * tileY;
if (tD1 > 360) {
Reverse(-1, startDTime_CTRL.value());
tD1 = 360;
} else if (tD1 < -360) {
Reverse(1, startDTime_CTRL.value());
tD1 = -360;
} else {
tD1 = tD1;
}
tA2 += endATime_CTRL.value() * reverse * tileX;
if (tA2 > 360) {
Reverse(-1, endATime_CTRL.value());
tA2 = 360;
} else if (tA2 < -360) {
Reverse(1, endATime_CTRL.value());
tA2 = -360;
} else {
tA2 = tA2;
}
tB2 += endBTime_CTRL.value() * reverse * tileX;
if (tB2 > 360) {
Reverse(-1, endBTime_CTRL.value());
tB2 = 360;
} else if (tB2 < -360) {
Reverse(1, endBTime_CTRL.value());
tB2 = -360;
} else {
tB2 = tB2;
}
tC2 += endCTime_CTRL.value() * reverse * tileY;
if (tC2 > 360) {
Reverse(-1, endCTime_CTRL.value());
tC2 = 360;
} else if (tC2 < -360) {
Reverse(1, endCTime_CTRL.value());
tC2 = -360;
} else {
tC2 = tC2;
}
tD2 += endDTime_CTRL.value() * reverse * tileY;
if (tD2 > 360) {
Reverse(-1, endDTime_CTRL.value());
tD2 = 360;
} else if (tD2 < -360) {
Reverse(1, endDTime_CTRL.value());
tD2 = -360;
} else {
tD2 = tD2;
}
function Reverse(x, CTRLValue) {
if (CTRLValue > 0) {
reverse = x;
} else if (CTRLValue < 0) {
reverse = -x;
} else {
reverse = x;
}
}
}
function exportSVG() {
if (frameCount == 0) {
createCanvas(900, windowHeight);
strokeWeight(1);
stroke(0);
fill(255);
} else {
createCanvas(1080, 1080, SVG);
strokeWeight(1);
stroke(0);
fill(255);
mode.value('circles');
redraw();
save("CirclePattern.svg"); // give file name
print("saved svg");
mode.value('squares');
redraw();
save("SquarePattern.svg"); // give file name
print("saved svg");
noCanvas();
remove();
new p5();
}
}