xxxxxxxxxx
306
//JS color matrix library for colorblindness simulation: http://web.archive.org/web/20081014161121/http://www.colorjack.com/labs/colormatrix/. Thanks to Emilio for sharing this library.
let zoomFrameTop0;
let zoomFrameBottom0;
let zoomFrameTop1;
let zoomFrameBottom1;
let zoom;
let videoNoShow;
let rcdReminder1;
let rcdReminder2;
let rcdReminder3;
let rcdReminderDismiss;
let colorBlindType = 'Protanopia';
function preload() {
zoomFrameTop0 = loadImage("/assets/zoom_top.png");
zoomFrameBottom0 = loadImage("/assets/zoom_bottom.png");
zoomFrameTop1 = loadImage("/assets/zoom_top_1.png");
zoomFrameBottom1 = loadImage("/assets/zoom_bottom_1.png");
}
/* Here we are calling the function */
function setup() {
createCanvas(640, 480);
frameRate(30);
cam = createCapture(VIDEO);
cam.hide();
zoom = new zoomFrame();
//zoom.showImage(colorBlindType);
noStroke();
//after 3 seconds, call recordingBegan to simulate beginning of recording.
setTimeout(recordingBegan, 8000);
}
function draw() {
push();
translate(width, 0);
scale(-1, 1);
image(cam, 0, 0);
pop();
cam.loadPixels();
blind();
zoom.showImage(colorBlindType);
//console.log(mouseX, mouseY);
}
function recordingBegan() {
console.log("recording began")
//show recording bottom
recording = createButton("●");
recording.position(40, 5);
recording.style("color", color(0, 139, 255));
recording.style("background-color", color(0, 0, 0, 0));
recording.style("font-size", 28 + "px");
recording.style("border", "none");
recordingText = createP("Meeting is being recorded");
recordingText.style("font-size", 15 + "px");
recordingText.style("color", color(255));
recordingText.position(70, 0);
//DOM: cover camera feed with black image
videoNoShow = createImg("/assets/noShowVideo.png", "hide video");
videoNoShow.position(0, 35)
videoNoShow.style("width", 640 + 'px');
videoNoShow.style("height", 410 + 'px');
//DOM: popup window informing people that recording has started. click ok button to dismiss. \
popup = createDiv('Please keep your audio and video off if you do not wish to be recorded.');
popup.style("border", 2 + "px");
popup.style("color", color(255));
popup.style("background-color", color(196, 196, 194, 95));
popup.style("padding", "50px");
popup.style("font-size", "18px");
popup.position(12, height/3 * 2);
popupDismissButton = createButton('Ok, I understand.')
popupDismissButton.position(width / 2 - 70, height - 80);
popupDismissButton.style('background-color', color(2, 117, 216));
popupDismissButton.style('padding', "8px");
popupDismissButton.style('color', color(255));
popupDismissButton.style('border', 'none');
popupDismissButton.style('border-radius', '10px');
popupDismissButton.mousePressed(closePopup);
//DOM: swap camera icon with no camera icon. Click on the icon will run askCamera function.
videoOffButton = createImg("/assets/videoOff.png", "cross out video icon");
videoOffButton.position(55, height - 28);
videoOffButton.style("width", 45 + 'px');
videoOffButton.style("height", 25 + 'px');
videoOffButton.mousePressed(askCamera);
//noShowVidButton
}
function openChat() {
chatBox = createImg("/assets/chat.png", "chat history");
chatBox.position(240, height / 5 - 20);
chatBox.style("width", 300 + 'px');
chatBox.style("height", 350 + 'px');
//create an invisible button cover over x
closeChatBox = createButton('x');
closeChatBox.position(510, 80);
closeChatBox.mousePressed(closeChat);
sel = createSelect();
sel.position(276, 352);
sel.option('host');
sel.option('everyone');
sel.option('Jason');
sel.option('...');
sel.selected('everyone');
sel.changed(recordingReminder);
}
function closeChat() {
sel.remove();
chatBox.remove();
rcdReminder1.remove();
rcdReminder2.remove();
rcdReminder3.remove();
rcdReminderDismiss.remove();
closeChatBox.remove();
}
function recordingReminder() {
let item = sel.value();
let reminderText = `▲ Recording in progress, your message to ${item} will be visible to ,everyone in the recording playback.`
reminderText = splitTokens(reminderText, ',');
rcdReminderDismiss = createButton('Okay, I am aware.');
rcdReminderDismiss.position(340, 172);
rcdReminderDismiss.style('background-color', color(2, 117, 216));
rcdReminderDismiss.style('padding', "8px");
rcdReminderDismiss.style('color', color(255));
rcdReminderDismiss.style('border', 'none');
rcdReminderDismiss.style('border-radius', '10px');
rcdReminderDismiss.hide();
rcdReminderDismiss.mousePressed(rcdDismiss);
rcdReminder1 = createDiv(reminderText[0]);
rcdReminder1.style("color", color(0, 139, 255));
rcdReminder1.style("background-color", color(255, 255, 255, 90));
rcdReminder1.style("padding", "5px");
rcdReminder1.position(265, 105);
rcdReminder1.hide();
rcdReminder2 = createDiv(reminderText[1]);
rcdReminder2.style("color", color(0, 139, 255));
rcdReminder2.style("background-color", color(255, 255, 255, 90));
rcdReminder2.style("padding", "5px");
rcdReminder2.position(265, 120);
rcdReminder2.hide();
rcdReminder3 = createDiv(reminderText[2]);
rcdReminder3.style("color", color(0, 139, 255));
rcdReminder3.style("background-color", color(255, 255, 255, 90));
rcdReminder3.style("padding", "5px");
rcdReminder3.position(265, 135);
rcdReminder3.hide();
if (item == 'Jason') {
rcdReminder1.show();
rcdReminder2.show();
rcdReminder3.show();
rcdReminderDismiss.show();
} else {
rcdReminder1.hide();
rcdReminder2.hide();
rcdReminder3.hide();
rcdReminderDismiss.hide();
}
}
function rcdDismiss() {
rcdReminder1.remove();
rcdReminder2.remove();
rcdReminder3.remove();
rcdReminderDismiss.remove();
}
function closePopup() {
popup.remove();
popupDismissButton.remove();
//DOM: click on chat area (invisible button?) will open a chat dialogue with reminder that no chat is private since recording is on.
chatButton = createImg("/assets/chatIcon.png", "open chat");
chatButton.position(290, height - 31);
chatButton.style("width", 40 + 'px');
chatButton.style("height", 30 + 'px');
chatButton.mousePressed(openChat);
}
function removeBlackCover() {
videoNoShow.remove();
videoOffButton.remove();
camQuestion.remove();
cameraConfirm.remove();
cameraDeny.remove();
}
function closeCamPopup() {
camQuestion.remove();
cameraConfirm.remove();
cameraDeny.remove();
}
function askCamera() {
//remind people that recording is on. Confirm to proceed with turning on video, remove black screen and camera icon. Or close diaglue.
camQuestion = createDiv('Recording, do you still wish to turn on the camera?');
camQuestion.style("border", 2 + "px");
camQuestion.style("color", color(255));
camQuestion.style("background-color", color(196, 196, 194, 90));
camQuestion.style("padding", "50px");
camQuestion.position(10, height - 160);
cameraConfirm = createButton('Yes, proceed')
cameraConfirm.position(width / 3, height - 80);
cameraConfirm.style('background-color', color(2, 117, 216));
cameraConfirm.style('padding', "8px");
cameraConfirm.style('color', color(255));
cameraConfirm.style('border', 'none');
cameraConfirm.style('border-radius', '10px');
cameraConfirm.mousePressed(removeBlackCover);
cameraDeny = createButton('Cancel')
cameraDeny.position(width / 5, height - 80);
cameraDeny.style('background-color', color(2, 117, 216));
cameraDeny.style('padding', "8px");
cameraDeny.style('color', color(255));
cameraDeny.style('border', 'none');
cameraDeny.style('border-radius', '10px');
cameraDeny.mousePressed(closeCamPopup);
}
function ColorMatrix(o, m) { // takes: RGBA object, Matrix array
function fu(n) {
let value = 0;
if (n <= 0) {
value = 0;
} else if (n < 255) {
value = n;
} else {
value = 255;
}
return value;
}
var r = ((o.R * m[0]) + (o.G * m[1]) + (o.B * m[2]) + (o.A * m[3]) + m[4]);
var g = ((o.R * m[5]) + (o.G * m[6]) + (o.B * m[7]) + (o.A * m[8]) + m[9]);
var b = ((o.R * m[10]) + (o.G * m[11]) + (o.B * m[12]) + (o.A * m[13]) + m[14]);
var a = ((o.R * m[15]) + (o.G * m[16]) + (o.B * m[17]) + (o.A * m[18]) + m[19]);
return ({
'R': fu(r),
'G': fu(g),
'B': fu(b),
'A': fu(a)
});
}
function Blind(v) { // this function just returns the Matrix
return ({
'Normal': [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
'Protanopia': [0.567, 0.433, 0, 0, 0, 0.558, 0.442, 0, 0, 0, 0, 0.242, 0.758, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]
}[v]);
}
function blind() {
for (let x = 0; x < cam.width; x += 3) {
for (let y = 0; y < cam.height; y += 3) {
let i = (y * cam.width + x) * 4;
let r = cam.pixels[i]
let b = cam.pixels[i + 1]
let g = cam.pixels[i + 2]
let a = cam.pixels[i + 3]
let newColor = ColorMatrix({
R: r,
G: g,
B: b,
A: a
}, Blind(colorBlindType));
fill(newColor.R, newColor.G, newColor.B, newColor.A);
rect(x, y, 3, 3);
}
}
}
function keyPressed() {
if (colorBlindType == 'Normal') {
console.log('intial: ' + colorBlindType)
colorBlindType = 'Protanopia'
} else {
colorBlindType = 'Normal'
}
}
class zoomFrame {
constructor() {
this.topX = 0;
this.topY = 0;
this.topHeight = 35;
this.bottomX = 0;
this.bottomY = height - 35;
this.bottomHeight = 35;
}
showImage(colorBlindType) {
if (colorBlindType == 'Normal') {
image(zoomFrameTop1, this.topX, this.topY, width, this.topHeight);
image(zoomFrameBottom1, this.bottomX, this.bottomY, width, this.bottomHeight);
} else {
image(zoomFrameTop0, this.topX, this.topY, width, this.topHeight);
image(zoomFrameBottom0, this.bottomX, this.bottomY, width, this.bottomHeight);
}
}
}