xxxxxxxxxx
877
let capture;
let brightnessFactor = 0;
let exposureFactor = 1.0;
let ycircle = 274;
let blockSize = 7;
let n = 0;
let q = 50;
// Desired aspect ratio
let aspectRatio = 4 / 3;
let arrowX = 20;
let arrowY = 20;
let selectedQuadrant = -1;
(function setDefaultOptions() {
P5Capture.setDefaultOptions({
disableUi: true,
format: "gif",
framerate: 15,
quality: 1,
width: arrowX,
});
})();
let useFrontCamera = false; // false for rear camera, true for front camera
let cameraConstraints = {
video: { facingMode: useFrontCamera ? "user" : "environment" },
audio: false,
};
let cols3 = ["#3F1820", "#307070", "#FFB88F", "#FFF8FF"];
let cols4 = ["#3F383F", "#1F48AF", "#80C86F", "#EFF8D0"];
let cols2 = ["#000000", "#606060", "#B0B0B0", "#FFF8FF"];
let cols1 = ["#00313d", "#ff6c72", "#ffcb8d", "#f1f2d7"];
let colsRects = [
{
x: arrowX * 30.6,
y: arrowY * 26.5,
w: arrowX * 1.6,
h: arrowX * 1.6,
colors: cols1,
},
{
x: arrowX * 32.4,
y: arrowY * 26.5,
w: arrowX * 1.6,
h: arrowX * 1.6,
colors: cols2,
},
{
x: arrowX * 34.2,
y: arrowY * 26.5,
w: arrowX * 1.6,
h: arrowX * 1.6,
colors: cols3,
},
{
x: arrowX * 36,
y: arrowY * 26.5,
w: 30,
h: 30,
colors: cols4,
},
];
//let currentColors = [cols1[0], cols1[1], cols1[2], cols1[3]];
let currentColors = cols1.map((hex) => hexToRgb(hex));
class HideUI {
constructor() {
this.isVisible = true; // Default UI visibility
this.buttonVisible = true;
this.buttonX = windowWidth / 1.063; // Position the button on the top right corner
this.buttonY = windowHeight / 1.165;
this.buttonWidth = arrowX / 20;
this.buttonHeight = arrowY / 40;
}
drawButton() {
if (!this.buttonVisible) return;
push(); // Start a new drawing state
fill(0); // Set button color
stroke(0);
rect(this.buttonX, this.buttonY, this.buttonWidth, this.buttonHeight, 5); // Draw the button with rounded corners
fill(255); // Set text color
noStroke();
textSize(12);
textAlign(CENTER, CENTER);
text(
"UI",
this.buttonX + this.buttonWidth / 2,
this.buttonY + this.buttonHeight / 2
); // Label the button
pop(); // Restore original drawing state
}
toggleUI() {
this.isVisible = !this.isVisible; // Toggle visibility state
}
checkMousePressed() {
// Check if the mouse is within the button bounds and toggle UI visibility
if (
mouseX >= this.buttonX &&
mouseX <= this.buttonX + this.buttonWidth &&
mouseY >= this.buttonY &&
mouseY <= this.buttonY + this.buttonHeight
) {
this.toggleUI();
}
}
// Method to call in the draw function to manage UI visibility
manageUI() {
if (this.isVisible) {
this.drawUIElements();
}
this.drawButton(); // Always draw the button so it can be interacted with
}
// Central method to draw all UI elements
drawUIElements() {
// Place all UI drawing code here, e.g., drawArrows(), sizeSlider(), etc.
// This example assumes these functions are defined elsewhere in your code
rects();
sizeSlider();
drawArrows();
stroke(0);
fill(255);
text(blockSize, width / 19, height / 1.36);
text(brightnessFactor, width / 19, height / 1.15);
text(exposureFactor, width / 8.5, height / 1.15);
// Add any other UI elements that need to be shown or hidden
}
}
class CameraSwapButton {
constructor(x, y, width, height, label, texts) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.label = label;
this.texts = texts;
this.isVisible = true;
}
drawButton() {
if (!this.isVisible) return;
push();
fill(0); // Set button color
stroke(0);
rect(this.x, this.y, this.width, this.height, 5); // Draw the button with rounded corners
fill(255); // Set text color
noStroke();
textSize(this.texts);
textAlign(CENTER, CENTER);
text(this.label, this.x + this.width / 2, this.y + this.height / 2); // Label the button
pop();
}
checkMousePressed() {
if (
mouseX >= this.x &&
mouseX <= this.x + this.width &&
mouseY >= this.y &&
mouseY <= this.y + this.height
) {
swapCamera(); // Call the function to swap the camera
}
}
updatePosition(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}
class ScreenshotButton {
constructor(x, y, width, height, label, texts) {
// Adjust these values to change the button's size and position
this.buttonWidth = windowWidth / 15;
this.buttonHeight = windowHeight / 12;
this.rounding = 10; // Rounded corner radius
// Position the button in the top right corner
this.isVisible = true; // Initially visible
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.label = label;
this.texts = texts;
}
drawButton() {
if (!this.isVisible) return; // Don't draw if set to invisible
push();
fill(0); // Black fill
noStroke();
rect(this.x, this.y, this.width, this.height, this.rounding); // Draw the button with rounded corners
//rect(this.x, this.y, this.buttonWidth, this.buttonHeight, this.rounding);
fill(255); // White text
textSize(this.texts);
textAlign(CENTER, CENTER);
textFont("Courier New");
text("⌞ ⌝", this.x + this.buttonWidth / 2, this.y + this.buttonHeight / 2);
pop();
}
checkMousePressed() {
if (!this.isVisible) return; // Don't detect if set to invisible
// Check if the mouse click is within the button's boundaries
if (
mouseX >= this.x &&
mouseX <= this.x + this.buttonWidth &&
mouseY >= this.y &&
mouseY <= this.y + this.buttonHeight
) {
this.takeScreenshot();
}
}
takeScreenshot() {
hideUIButton.isVisible = false;
hideUIButton.buttonVisible = false;
videoRecordButton.isVisible = false;
cameraSwapButton.isVisible = false;
this.isVisible = false; // Temporarily hide the button
draw(); // Redraw the canvas without the button
setTimeout(() => {
saveCanvas("screenshot", "png"); // Take the screenshot
this.isVisible = true;
videoRecordButton.isVisible = true;
hideUIButton.isVisible = true; // Show the UI again
hideUIButton.buttonVisible = true;
cameraSwapButton.isVisible = true;
draw(); // Redraw the canvas to show the UI again
}, 50); // Delay to ensure the canvas is updated, adjust time as needed
}
}
class VideoRecordButton {
constructor(x, y, width, height, label, texts) {
// Adjust these values to position the button below the ScreenshotButton
this.buttonWidth = windowWidth / 15;
this.buttonHeight = windowHeight / 12;
this.rounding = 10; // Rounded corner radius
// Position the button below the ScreenshotButton with some padding
this.x = x; // Same padding from the right edge as ScreenshotButton
this.y = y; // Below the ScreenshotButton with padding
this.isRecording = false; // State to track recording status
this.isVisible = true; // Initially visible
// Configure the capturer: specify format and framerate
this.captureInstance = P5Capture.getInstance();
this.width = width;
this.height = height;
this.label = label;
this.texts = texts;
}
drawButton(g) {
if (!this.isVisible) return; // Don't draw if set to invisible
g.push();
g.fill(this.isRecording ? color(255, 0, 0) : color(0)); // Red fill when recording, black otherwise
g.noStroke();
//rect(this.x, this.y, this.buttonWidth, this.buttonHeight, this.rounding);
g.rect(this.x, this.y, this.width, this.height, this.rounding); // Draw the button with rounded corners
g.fill(255); // White text for visibility
g.textSize(this.texts);
g.textAlign(CENTER, CENTER);
g.textFont("Courier New");
g.text(
this.isRecording ? "■" : "●",
this.x + this.width / 2,
this.y + this.height / 2
);
g.pop();
}
toggleRecording() {
this.isRecording = !this.isRecording;
if (this.isRecording) {
hideUIButton.isVisible = false;
hideUIButton.buttonVisible = false;
screenshotButton.isVisible = false;
cameraSwapButton.isVisible = false;
videoRecordButton.isVisible = false;
//this.isVisible = false; // Temporarily hide the button
draw(); // Redraw the canvas without the button
// Start recording
this.captureInstance.start({
format: "gif", // or other formats like "gif", "mp4", etc.
framerate: 15, // Example framerate
// Add more options as needed
width: windowWidth,
});
} else {
// Stop recording and start encoding. Download will start automatically after encoding
this.captureInstance.stop();
//this.isVisible = true;
hideUIButton.isVisible = true; // Show the UI again
hideUIButton.buttonVisible = true;
screenshotButton.isVisible = true;
cameraSwapButton.isVisible = true;
videoRecordButton.isVisible = true;
}
}
checkMousePressed() {
if (!this.isVisible) {
if (
mouseX >= windowWidth - windowWidth &&
mouseX <= windowWidth &&
mouseY >= windowHeight - windowHeight &&
mouseY <= windowHeight
) {
this.toggleRecording();
}
} // if invisible any part of the screen stop recording
else {
// Check if the mouse click is within the button's boundaries
if (
mouseX >= this.x &&
mouseX <= this.x + this.buttonWidth &&
mouseY >= this.y &&
mouseY <= this.y + this.buttonHeight
) {
this.toggleRecording();
}
}
}
}
// Create an instance of the HideUI class
let hideUIButton;
let cameraSwapButton;
let screenshotButton;
let videoRecordButton;
let uiLayer;
function preload() {
font = loadFont("pixel.ttf");
}
function hexToRgb(hex) {
let r = parseInt(hex.slice(1, 3), 16);
let g = parseInt(hex.slice(3, 5), 16);
let b = parseInt(hex.slice(5, 7), 16);
return [r, g, b];
}
let color1 = hexToRgb("#FFB88F");
let color2 = hexToRgb("#80C86F");
let color3 = hexToRgb("#B0B0B0");
let color4 = hexToRgb("#ff6c72");
function setup() {
hideUIButton = new HideUI();
createCanvas(windowWidth, windowHeight); // Use window dimensions
uiLayer = createGraphics(windowWidth, windowHeight);
startCapture();
pixelDensity(1);
frameRate(15);
exposureFactor = 1.0;
strokeCap(SQUARE);
strokeWeight(1);
textFont(font);
textSize(20);
textAlign(CENTER, CENTER);
cameraSwapButton = new CameraSwapButton(
windowWidth / 1.18,
windowHeight / 75,
arrowX / 24,
arrowY / 24,
"[o°]",
20
);
screenshotButton = new ScreenshotButton(
windowWidth / 1.1,
windowHeight / 20,
0,
0,
30 /*arrowX / 15, arrowY / 12,*/
);
videoRecordButton = new VideoRecordButton(
windowWidth / 1.1,
windowHeight / 7.5,
0,
0,
40
);
windowResized();
}
function drawUIElements() {
uiLayer.clear(); // Clear previous drawings
videoRecordButton.drawButton(uiLayer); // Draw the button on the uiLayer
}
function startCapture() {
if (capture) {
capture.remove(); // Stop and remove the existing capture if it exists
}
capture = createCapture(cameraConstraints, function (stream) {
// This callback ensures the stream is ready and dimensions are set
//let track = stream.getVideoTracks()[0];
//let settings = track.getSettings();
// Calculate the aspect ratio
//aspectRatio = settings.aspectRatio || windowWidth / windowHeight;
aspectRatio = settings.aspectRatio || capture.width / capture.height;
//aspectRatio = windowWidth / windowHeight;
// Call windowResized to adjust layout based on the new aspect ratio
windowResized();
});
capture.size(windowWidth, windowHeight);
capture.hide();
}
// Function to swap between the front and rear cameras
function swapCamera() {
useFrontCamera = !useFrontCamera; // Toggle the camera type
cameraConstraints.video.facingMode = useFrontCamera ? "user" : "environment"; // Update constraints
startCapture(); // Restart the capture with the new constraints
}
function windowResized() {
// Calculate max possible width based on window height
let newWidth = windowHeight * aspectRatio;
let newHeight = windowHeight;
arrowX = newWidth;
arrowY = newHeight;
//aspectRatio = newWidth / newHeight;
//aspectRatio = capture.width / capture.height;
// If calculated width is wider than window, adjust based on width instead
if (newWidth > windowWidth) {
newWidth = windowWidth;
console.log(newWidth);
newHeight = windowWidth / aspectRatio;
console.log(newHeight);
arrowX = newWidth;
arrowY = newHeight;
//aspectRatio = newWidth / newHeight;
//aspectRatio = capture.width / capture.height;
}
// Resize the canvas and video capture to match new dimensions
resizeCanvas(newWidth, newHeight);
capture.size(newWidth, newHeight);
// Optionally, adjust other elements' sizes or positions based on the new canvas size
colsRects = [
{
x: arrowX / 1.235,
y: arrowY / 1.08,
w: arrowX / 25,
h: arrowX / 25,
colors: cols1,
},
{
x: arrowX / 1.165,
y: arrowY / 1.08,
w: arrowX / 25,
h: arrowX / 25,
colors: cols2,
},
{
x: arrowX / 1.105,
y: arrowY / 1.08,
w: arrowX / 25,
h: arrowX / 25,
colors: cols3,
},
{
x: arrowX / 1.05,
y: arrowY / 1.08,
w: arrowX / 25,
h: arrowX / 25,
colors: cols4,
},
];
ycircle = arrowY / 1.55;
hideUIButton.buttonX = windowWidth / 1.04;
hideUIButton.buttonY = windowHeight / 80;
hideUIButton.buttonWidth = arrowX / 30;
hideUIButton.buttonHeight = arrowY / 25;
cameraSwapButton.texts = windowWidth / 50;
screenshotButton.x = windowWidth / 1.1; // Update to desired position
screenshotButton.y = windowHeight / 20; // Update to desired position
screenshotButton.texts = windowWidth / 30;
//screenshotButton.width = windowWidth / 15; // Update to desired size
//screenshotButton.height = windowHeight / 12; // Update to desired size
videoRecordButton.x = windowWidth / 1.1; // Update to desired position
videoRecordButton.y = windowHeight / 7.5; // Update to desired position
videoRecordButton.width = arrowX / 14.5; // Update to desired size
videoRecordButton.height = arrowY / 10; // Update to desired size
videoRecordButton.texts = windowWidth / 20;
if (cameraSwapButton) {
cameraSwapButton.updatePosition(
windowWidth / 1.18,
windowHeight / 75,
arrowX / 24,
arrowY / 24
);
}
startCapture();
}
function draw() {
strokeWeight(1);
background(0);
if (capture.width > 0 && capture.height > 0) {
capture.loadPixels();
}
let w = capture.width;
let h = capture.height;
let blocksX = Math.ceil(w / blockSize);
let blocksY = Math.ceil(h / blockSize);
//let blocksX = Math.floor((w / blockSize));
//let blocksY = Math.floor((h / blockSize));
blockSize = round(map(ycircle, arrowY / 5.5, arrowY / 1.4, q, 1), n);
//console.log(blockSize);
//console.log(ycircle);
push();
translate(width, 0);
scale(-1, 1);
for (let by = 0; by < blocksY; by++) {
for (let bx = 0; bx < blocksX; bx++) {
grayscaleBlock(bx * blockSize, by * blockSize, blockSize, blockSize);
}
}
capture.updatePixels();
image(capture, 0, 0);
pop();
stroke(1);
/*drawArrows();
sizeSlider();
stroke(255);
text(blockSize, width / 19, height / 1.36);
text(brightnessFactor, width / 19, height / 1.15);
text(exposureFactor, width / 8.5, height / 1.15);
*/
screenshotButton.drawButton();
hideUIButton.manageUI();
//videoRecordButton.drawButton();
cameraSwapButton.drawButton();
drawUIElements();
image(uiLayer, 0, 0);
}
function grayscaleBlock(x, y, w, h) {
let i = (x + y * capture.width) * 4;
let sum = 0;
let count = 0;
for (let by = 0; by < h; by++) {
for (let bx = 0; bx < w; bx++) {
let idx = i + (bx + by * capture.width) * 4;
let r = capture.pixels[idx];
let g = capture.pixels[idx + 1];
let b = capture.pixels[idx + 2];
let avg = (r + g + b) / 3;
sum += avg;
count++;
}
}
let blockAvg = Math.floor(sum / count);
blockAvg = blockAvg + brightnessFactor;
blockAvg = constrain(blockAvg, 0, 255); // Ensure within range
let color;
if (blockAvg < 64) {
color = currentColors[0];
} else if (blockAvg < 128) {
color = currentColors[1];
} else if (blockAvg < 192) {
color = currentColors[2];
} else {
color = currentColors[3];
}
let adjustedColor = adjustExposure(color, exposureFactor);
for (let by = 0; by < h; by++) {
for (let bx = 0; bx < w; bx++) {
let idx = i + (bx + by * capture.width) * 4;
capture.pixels[idx] = adjustedColor[0];
capture.pixels[idx + 1] = adjustedColor[1];
capture.pixels[idx + 2] = adjustedColor[2];
}
}
}
function keyPressed() {
if (keyCode === UP_ARROW) {
brightnessFactor += 10;
} else if (keyCode === DOWN_ARROW) {
brightnessFactor -= 10;
} else if (keyCode === RIGHT_ARROW) {
exposureFactor += 0.1; // Increase exposure
exposureFactor = round(constrain(exposureFactor, 0.1, 3), 1); // Example range, adjust as needed
} else if (keyCode === LEFT_ARROW) {
exposureFactor -= 0.1; // Decrease exposure
exposureFactor = round(constrain(exposureFactor, 0.1, 3), 1); // Example range, adjust as needed
}
brightnessFactor = constrain(brightnessFactor, -255, 255);
}
function adjustExposure(color, exposureFactor) {
// Ensure color is an array; if not, attempt to convert or return black on error
if (!Array.isArray(color)) {
console.error("Invalid color input passed to adjustExposure:", color);
return [0, 0, 0]; // Return black or any default color in case of error
}
// Adjust each color component by the exposure factor and ensure it's within the valid range
return color.map((c) => constrain(Math.floor(c * exposureFactor), 0, 255));
}
function drawArrows() {
// Draw Up Arrow
stroke(0);
fill(255); // White color
triangle(
arrowX / 30,
arrowY / 1.08,
arrowX / 20,
arrowY / 1.12,
arrowX / 15,
arrowY / 1.08
); // Adjust coordinates as needed
// Draw Down Arrow
fill(255); // White color
triangle(
arrowX / 30,
arrowY / 1.05,
arrowX / 20,
arrowY / 1.015,
arrowX / 15,
arrowY / 1.05
); // Adjust coordinates as needed
//noStroke();
// Draw Up Arrow
fill(0); // Black color
triangle(
arrowX / 10,
arrowY / 1.08,
arrowX / 8.5,
arrowY / 1.12,
arrowX / 7.5,
arrowY / 1.08
); // Adjust coordinates as needed
//noStroke();
// Draw Down Arrow
fill(0); // Black color
triangle(
arrowX / 10,
arrowY / 1.05,
arrowX / 8.5,
arrowY / 1.015,
arrowX / 7.5,
arrowY / 1.05
); // Adjust coordinates as needed
//noStroke();
noFill();
strokeWeight(2);
circle(arrowX / 20, arrowY / 7, 15);
strokeWeight(1);
noStroke();
/* fill(cols1[0]);
rect(arrowX / 1.235, arrowY / 1.08, arrowX / 50, arrowX / 50);
fill(cols1[2]);
rect(arrowX / 1.235, arrowY / 1.05, arrowX / 50, arrowX / 50);
fill(cols1[3]);
rect(arrowX / 1.206, arrowY / 1.05, arrowX / 50, arrowX / 50);
fill(cols2[0]);
rect(arrowX / 1.165, arrowY / 1.08, arrowX / 50, arrowX / 50);
fill(cols2[2]);
rect(arrowX / 1.165, arrowY / 1.05, arrowX / 50, arrowX / 50);
fill(cols2[3]);
rect(arrowX / 1.139, arrowY / 1.05, arrowX / 50, arrowX / 50);
fill(cols3[0]);
rect(arrowX / 1.105, arrowY / 1.08, arrowX / 50, arrowX / 50);
fill(cols3[2]);
rect(arrowX / 1.105, arrowY / 1.05, arrowX / 50, arrowX / 50);
fill(cols3[3]);
rect(arrowX / 1.082, arrowY / 1.05, arrowX / 50, arrowX / 50);
fill(cols4[0]);
rect(arrowX / 1.05, arrowY / 1.08, arrowX / 50, arrowX / 50);
fill(cols4[2]);
rect(arrowX / 1.05, arrowY / 1.05, arrowX / 50, arrowX / 50);
fill(cols4[3]);
rect(arrowX / 1.029, arrowY / 1.05, arrowX / 50, arrowX / 50);
*/
strokeWeight(1);
}
function mousePressed() {
hideUIButton.checkMousePressed();
cameraSwapButton.checkMousePressed();
screenshotButton.checkMousePressed();
videoRecordButton.checkMousePressed();
// Check for color palette selection
if (hideUIButton.isVisible) {
for (let rectInfo of colsRects) {
if (
mouseX >= rectInfo.x &&
mouseX <= rectInfo.x + rectInfo.w &&
mouseY >= rectInfo.y &&
mouseY <= rectInfo.y + rectInfo.h
) {
currentColors = rectInfo.colors.map((hex) => hexToRgb(hex));
//currentColors = rectInfo.colors.map((color));
break;
}
}
// Check for Up Arrow click
if (
mouseX >= arrowX / 40 &&
mouseX <= arrowX / 13 &&
mouseY >= arrowY / 1.12 &&
mouseY <= arrowY / 1.08
) {
brightnessFactor += 10; // Increase brightness
}
// Check for Down Arrow click
if (
mouseX >= arrowX / 40 &&
mouseX <= arrowX / 13 &&
mouseY >= arrowY / 1.05 &&
mouseY <= arrowY / 1.02
) {
brightnessFactor -= 10; // Decrease brightness
}
// Check for Up Arrow click
if (
mouseX >= arrowX / 11 &&
mouseX <= arrowX / 7 &&
mouseY >= arrowY / 1.12 &&
mouseY <= arrowY / 1.08
) {
exposureFactor = round(exposureFactor + 0.1, 1); // Increase brightness
}
// Check for Down Arrow click
if (
mouseX >= arrowX / 11 &&
mouseX <= arrowX / 7 &&
mouseY >= arrowY / 1.05 &&
mouseY <= arrowY / 1.02
) {
exposureFactor = round(exposureFactor - 0.1, 1); // Decrease brightness
}
//slider
if (
mouseX >= arrowX / 22 &&
mouseX <= arrowX / 18 &&
mouseY >= arrowY / 5.5 &&
mouseY <= arrowY / 1.4
) {
ycircle = mouseY;
//arrowX/22, arrowY/5.5, arrowX/20, arrowY/1.4
}
//glitch button
//arrowX/20, arrowY/7, 15
if (
mouseX >= arrowX / 22 &&
mouseX <= arrowX / 18 &&
mouseY >= arrowY / 8 &&
mouseY <= arrowY / 6
) {
if (n == 0) {
n = 1;
} else {
n = 0;
}
if (q == 50) {
q = 10;
} else {
q = 50;
}
fill(255);
circle(arrowX / 20, arrowY / 7, 15);
}
}
colsRects.forEach((rect, index) => {
if (
mouseX >= rect.x &&
mouseX <= rect.x + rect.w &&
mouseY >= rect.y &&
mouseY <= rect.y + rect.h
) {
selectedQuadrant = index; // Set the selected quadrant
}
});
brightnessFactor = constrain(brightnessFactor, -255, 255); // Ensure the brightnessFactor stays within bounds
exposureFactor = constrain(exposureFactor, 0.1, 3); // Ensure the brightnessFactor stays within bounds
}
function rgbToHex(r, g, b) {
return "#" + [r, g, b].map(x => {
const hex = x.toString(16);
return hex.length === 1 ? "0" + hex : hex;
}).join('').toUpperCase();
}
function mouseDragged() {
if (selectedQuadrant != -1) {
let rect = colsRects[selectedQuadrant];
let relX = mouseX - rect.x;
let relY = mouseY - rect.y;
let r = Math.round(map(relX, 0, rect.w, 0, 255));
let g = Math.round(map(relY, 0, rect.h, 0, 255));
let b = Math.round((255 - r + 255 - g) / 2);
// Convert RGB to Hex and update the colors of the selected rect
rect.colors = [rgbToHex(r, g, b)]; // Correctly using rect here
}
}
function sizeSlider() {
strokeWeight(5);
strokeCap(ROUND);
stroke(0);
line(arrowX / 20, arrowY / 5.5, arrowX / 20, arrowY / 1.4);
fill(255);
circle(arrowX / 20, ycircle, 12);
strokeWeight(1);
}
function rects() {
for (let rectInfo of colsRects) {
fill(rectInfo.colors); // Assuming rectInfo.colors is a hex string
rect(rectInfo.x, rectInfo.y, rectInfo.w, rectInfo.h);
}
}