top of page

let video;
let myFaceMesh;
let myResults = [];
let options = { maxFaces: 1, refineLandmarks: true, flipHorizontal: false };
let sourceImage;
let useWebcam = true;
let imageInput;
let sourceButton;
let sourceLabel;
let resetButton;
let hideButton;
let hasWebcam = true;
let showWebcamImage = true;
let greenMode = false;
let letterAssignments = [];
const step = 5;
let displayWidth, displayHeight, xOffset, yOffset, scaleFactorX, scaleFactorY;
let mirrorMode = false;
let mirrorTarget = 0;
let mirrorProgress = 0;
let symmetryMode = false;
let symmetryTarget = 0;
let symmetryProgress = 0;
let distortionActive = false;
let candidate1 = null;
let candidate2 = null;
let stretchEffects = {};
let glitchColumns = [];
let trailActive = false;
let trailEffects = {};
let loadingIconActive = false;
let loadingIconStart = 0;
let finalMessage = "";

function initGlitchColumns() {
let colWidth = 20;
glitchColumns = [];
for (let x = 0; x < width; x += colWidth) {
let rows = ceil(height / 20) + 1;
let col = {
x: x,
offset: random(5),
speed: random(0.1, 0.3),
digits: [],
phases: []
};
for (let i = 0; i < rows; i++) {
col.digits.push(floor(random(2)).toString());
col.phases.push(random(TWO_PI));
}
glitchColumns.push(col);
}
}

function drawGlitchBackground() {
let colWidth = 20;
textSize(16);
textAlign(CENTER, CENTER);
for (let col of glitchColumns) {
    
col.offset += col.speed * 0.01;
if (col.offset > 20) {
col.offset -= 20;
      
col.digits.shift();
col.digits.push(floor(random(2)).toString());
col.phases.shift();
col.phases.push(random(TWO_PI));
}
let rows = col.digits.length;
for (let i = 0; i < rows; i++) {
let y = i * 20 - col.offset;
      
col.phases[i] += 0.0005;
let phase = col.phases[i];
let d =
random() < 0.2
? String.fromCharCode(floor(random(65, 91)))
: sin(phase) > 0
? "1"
: "0";
let factor = (sin(phase) + 1) / 2;
let fillColor = lerpColor(color(0, 0, 0, 255), color(0, 255, 0, 255), factor);
fill(fillColor);
noStroke();
text(d, col.x + colWidth / 2, y);
}
}
}

function preload() {
myFaceMesh = ml5.faceMesh(options);
sourceImage = loadImage('face1.jpg');
}

function setup() {
createCanvas(600, 450);
initGlitchColumns();

try {
video = createCapture(VIDEO, () => console.log("Webcam connected"));
video.hide();
video.size(600, 450);
video.elt.addEventListener('error', e => {
console.log("Webcam error:", e);
hasWebcam = false;
updateUIForWebcamStatus();
});
} catch (e) {
console.log("Error creating webcam:", e);
hasWebcam = false;
updateUIForWebcamStatus();
}
 

hideButton = createButton('Hide');

hideButton.style('font-size', '32px');
hideButton.style('color', '#000000');
hideButton.style('background-color', 'transparent');
hideButton.style('border', 'none');
hideButton.mousePressed(toggleHide);
hideButton.hide();
 
setTimeout(() => {
let btnWidth = hideButton.elt.offsetWidth;
let btnHeight = hideButton.elt.offsetHeight;
hideButton.position((width - btnWidth) / 2 - 40, height - btnHeight - 40);
}, 100);
 
updateUIForWebcamStatus();
}

function updateUIForWebcamStatus() {
if (!hasWebcam) {
console.log("Webcam Not Available");
} else {
console.log("Webcam Available");
}
}

function handleImageUpload(file) {
if (file.type === 'image') {
loadImage(file.data, img => {
sourceImage = img;
if (!useWebcam && sourceImage) {
myFaceMesh.detectStart(sourceImage, gotResults);
}
 

hide in web
by marianna bezhanyan

//concept: you are cyber-criminal mal1cewar3 that fbi has been hunting for for years. you receive a message from your friend that they started to track you and you need to hide yourself in the web using encripted mask.
//Inspired by anti-face-detection make-up used by russian protestors to avoid face recognition cameras used for political repressions.

startMessages = { start1: "you're tracked. i repeat, mal1cewar3, they are after you. run. you have to code yourself into the matrix and hide in the web so they cant detect your face. click space to continue", start2: "use different letters and numbers to code a mask that distorts the image that fbi scans to search for you. when the mask is perfect -- press hide. click space to start"}; 

 

hide in web is inspired by my experience protesting Putin’s regime, where state-controlled facial recognition is used to track and detain dissenters. In Russia, an extensive network of over 200,000 AI-powered surveillance cameras enables real-time identification of protesters, often leading to immediate arrests.

In response, activists developed creative resistance tactics, including face-distorting makeup designed to disrupt facial recognition algorithms. By applying geometric patterns and asymmetrical shapes, they could obscure key facial markers and evade detection. Hide in Web reimagines this strategy in an interactive digital space, encoding users’ facial data into abstract symbols and transforming them into cybercriminals fleeing FBI surveillance.

Through an immersive experience, the project challenges users to navigate a world where personal data is weaponized.

let video;
let myFaceMesh;
let myResults = [];
let options = { maxFaces: 1, refineLandmarks: true, flipHorizontal: false };
let sourceImage;
let useWebcam = true;
let imageInput;
let sourceButton;
let sourceLabel;
let resetButton;
let hideButton;
let hasWebcam = true;
let showWebcamImage = true;
let greenMode = false;
let letterAssignments = [];
const step = 5;
let displayWidth, displayHeight, xOffset, yOffset, scaleFactorX, scaleFactorY;
let mirrorMode = false;
let mirrorTarget = 0;
let mirrorProgress = 0;
let symmetryMode = false;
let symmetryTarget = 0;
let symmetryProgress = 0;
let distortionActive = false;
let candidate1 = null;
let candidate2 = null;
let stretchEffects = {};
let glitchColumns = [];
let trailActive = false;
let trailEffects = {};
let loadingIconActive = false;
let loadingIconStart = 0;
let finalMessage = "";

function initGlitchColumns() {
  let colWidth = 20;
  glitchColumns = [];
  for (let x = 0; x < width; x += colWidth) {
    let rows = ceil(height / 20) + 1;
    let col = {
      x: x,
      offset: random(5),
      speed: random(0.1, 0.3),
      digits: [],
      phases: []
    };
    for (let i = 0; i < rows; i++) {
      col.digits.push(floor(random(2)).toString());
      col.phases.push(random(TWO_PI));
    }
    glitchColumns.push(col);
  }
}

function drawGlitchBackground() {
  let colWidth = 20;
  textSize(16);
  textAlign(CENTER, CENTER);
  for (let col of glitchColumns) {
    
    col.offset += col.speed * 0.01;
    if (col.offset > 20) {
      col.offset -= 20;
      
      col.digits.shift();
      col.digits.push(floor(random(2)).toString());
      col.phases.shift();
      col.phases.push(random(TWO_PI));
    }
    let rows = col.digits.length;
    for (let i = 0; i < rows; i++) {
      let y = i * 20 - col.offset;
      
      col.phases[i] += 0.0005;
      let phase = col.phases[i];
      let d =
        random() < 0.2
          ? String.fromCharCode(floor(random(65, 91)))
          : sin(phase) > 0
          ? "1"
          : "0";
      let factor = (sin(phase) + 1) / 2;
      let fillColor = lerpColor(color(0, 0, 0, 255), color(0, 255, 0, 255), factor);
      fill(fillColor);
      noStroke();
      text(d, col.x + colWidth / 2, y);
    }
  }
}

function preload() {
  myFaceMesh = ml5.faceMesh(options);
  sourceImage = loadImage('face1.jpg');
}

function setup() {
  createCanvas(600, 450);
  initGlitchColumns();

  try {
    video = createCapture(VIDEO, () => console.log("Webcam connected"));
    video.hide();
    video.size(600, 450);
    video.elt.addEventListener('error', e => {
      console.log("Webcam error:", e);
      hasWebcam = false;
      updateUIForWebcamStatus();
    });
  } catch (e) {
    console.log("Error creating webcam:", e);
    hasWebcam = false;
    updateUIForWebcamStatus();
  }
 

  hideButton = createButton('Hide');

  hideButton.style('font-size', '32px');
  hideButton.style('color', '#000000');
  hideButton.style('background-color', 'transparent');
  hideButton.style('border', 'none');
  hideButton.mousePressed(toggleHide);
  hideButton.hide();
 
  setTimeout(() => {
    let btnWidth = hideButton.elt.offsetWidth;
    let btnHeight = hideButton.elt.offsetHeight;
    hideButton.position((width - btnWidth) / 2 - 40, height - btnHeight - 40);
  }, 100);
 
  updateUIForWebcamStatus();
}

function updateUIForWebcamStatus() {
  if (!hasWebcam) {
    console.log("Webcam Not Available");
  } else {
    console.log("Webcam Available");
  }
}

function handleImageUpload(file) {
  if (file.type === 'image') {
    loadImage(file.data, img => {
      sourceImage = img;
      if (!useWebcam && sourceImage) {
        myFaceMesh.detectStart(sourceImage, gotResults);
      }
 

oocky boocky

bottom of page