xxxxxxxxxx
745
let capture;
let brightnessFactor = 0;
let exposureFactor = 1.0;
let ycircle = 274;
let blockSize = 7;
let n = 0;
let q = 50;
// Desired aspect ratio
const aspectRatio = 4 / 3;
let arrowX = 20;
let arrowY = 20;
(function setDefaultOptions() {
P5Capture.setDefaultOptions({
disableUi: true,
format: "MP4",
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);
cameraSwapButton.drawButton();
// Add any other UI elements that need to be shown or hidden
}
}
class CameraSwapButton {
constructor(x, y, width, height, label) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.label = label;
}
drawButton() {
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(20);
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() {
// 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.x = windowWidth - this.buttonWidth - 20; // 20 pixels padding from the right edge
this.y = 20; // 20 pixels padding from the top edge
this.isVisible = true; // Initially visible
}
drawButton() {
if (!this.isVisible) return; // Don't draw if set to invisible
push();
fill(0); // Black fill
noStroke();
rect(this.x, this.y, this.buttonWidth, this.buttonHeight, this.rounding);
fill(255); // White text
textSize(30);
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;
this.isVisible = false; // Temporarily hide the button
draw(); // Redraw the canvas without the button
setTimeout(() => {
saveCanvas('screenshot', 'png'); // Take the screenshot
this.isVisible = true;
hideUIButton.isVisible = true; // Show the UI again
hideUIButton.buttonVisible = 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() {
// 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 = windowWidth - this.buttonWidth - 20; // Same padding from the right edge as ScreenshotButton
this.y = 40 + this.buttonHeight; // 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();
}
drawButton() {
if (!this.isVisible) return; // Don't draw if set to invisible
push();
fill(this.isRecording ? color(255, 0, 0) : color(0)); // Red fill when recording, black otherwise
noStroke();
rect(this.x, this.y, this.buttonWidth, this.buttonHeight, this.rounding);
fill(255); // White text for visibility
textSize(40);
textAlign(CENTER, CENTER);
textFont('Courier New');
text(this.isRecording ? '■' : '●', this.x + this.buttonWidth / 2, this.y + this.buttonHeight / 2);
pop();
}
toggleRecording() {
this.isRecording = !this.isRecording;
if (this.isRecording) {
hideUIButton.isVisible = false;
hideUIButton.buttonVisible = false;
ScreenshotButton.isVisible = false;
//this.isVisible = false; // Temporarily hide the button
draw(); // Redraw the canvas without the button
// Start recording
this.captureInstance.start({
format: "webm", // 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;
}
}
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.toggleRecording();
}
}
}
// Create an instance of the HideUI class
let hideUIButton;
let cameraSwapButton;
let screenshotButton;
let videoRecordButton;
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
startCapture();
windowResized();
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°]");
screenshotButton = new ScreenshotButton();
videoRecordButton = new VideoRecordButton();
}
function startCapture() {
if (capture) {
capture.remove(); // Stop and remove the existing capture if it exists
}
capture = createCapture(cameraConstraints);
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;
// 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;
}
// 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 = arrowX / 1.063;
hideUIButton.buttonY = arrowY / 1.165;
hideUIButton.buttonWidth = arrowX / 20;
hideUIButton.buttonHeight = arrowY / 20;
if (cameraSwapButton) {
cameraSwapButton.updatePosition(windowWidth / 1.18, windowHeight / 75, arrowX / 24, arrowY / 24);
}
}
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();
}
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 / 40,
arrowY / 1.08,
arrowX / 20,
arrowY / 1.12,
arrowX / 13,
arrowY / 1.08
); // Adjust coordinates as needed
// Draw Down Arrow
fill(255); // White color
triangle(
arrowX / 40,
arrowY / 1.05,
arrowX / 20,
arrowY / 1.02,
arrowX / 13,
arrowY / 1.05
); // Adjust coordinates as needed
//noStroke();
// Draw Up Arrow
fill(0); // Black color
triangle(
arrowX / 11,
arrowY / 1.08,
arrowX / 8.5,
arrowY / 1.12,
arrowX / 7,
arrowY / 1.08
); // Adjust coordinates as needed
//noStroke();
// Draw Down Arrow
fill(0); // Black color
triangle(
arrowX / 11,
arrowY / 1.05,
arrowX / 8.5,
arrowY / 1.02,
arrowX / 7,
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));
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);
}
}
brightnessFactor = constrain(brightnessFactor, -255, 255); // Ensure the brightnessFactor stays within bounds
exposureFactor = constrain(exposureFactor, 0.1, 3); // Ensure the brightnessFactor stays within bounds
}
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() {
//add all 4 colors to rect image
for (let rectInfo of colsRects) {
fill(
hexToRgb(rectInfo.colors[1])[0],
hexToRgb(rectInfo.colors[0])[1],
hexToRgb(rectInfo.colors[0])[2]
);
rect(rectInfo.x, rectInfo.y, rectInfo.w, rectInfo.h);
}
}