Any Ideas: Obstruct Flow Fields By An Image

Hey all!

I was wondering if anyones creative genius could help.

I’m designing an app and I have a loading screen, where I want flow fields to generate to represent the data being pulled together and give the user something to look at whilst waiting.

I’ve create generally what I want, a flow fields in a circle, with my logo in the centre to act as an invisible block. However, I want my logo to be more visible, like the when the flow field goes through it’s, it’s blocked, but then comes out at the other side of my logo image, so that as more of the flow field is generated, more of my logo appears.

Any creative ideas would be much appreciated.
Thanks folks.

Here’s the code so far:

let particles = [];
let currentNum = 0;
const maxNum = 4500;
const incrementRate = 3;
const noiseScale = 0.01;
let radius = 200;
let img;

function preload() {
  img = loadImage('BuildPrompt_B_Blue.png', function() {
    let scalingFactor = (radius * 2) * 0.75 / max(img.width, img.height);
    img.resize(img.width * scalingFactor, img.height * scalingFactor);
    img.loadPixels();
  });
}

function setup() {
  createCanvas(400, 400);
  for (let i = 0; i < currentNum; i++) {
    particles.push(randomPointInCircle());
  }
  stroke('#ccffdd');
}

function draw() {
  background(34, 17, 188, 10);

  if (currentNum < maxNum) {
    for (let i = 0; i < incrementRate; i++) {
      particles.push(randomPointInCircle());
    }
    currentNum += incrementRate;
  }

  for (let p of particles) {
    point(p.x, p.y);
    let n = noise(p.x * noiseScale, p.y * noiseScale);
    let a = TAU * n;
    
    let newX = p.x + cos(a);
    let newY = p.y + sin(a);
    
    if (inImageRect(createVector(newX, newY)) && !isTransparent(newX, newY)) {
        // Redirecting based on the closest edge
        if (abs(newX - (width/2 - 5)) < img.width/2) {
            newX = p.x - cos(a);
        } else {
            newX = p.x + cos(a);
        }
        if (abs(newY - height/2) < img.height/2) {
            newY = p.y - sin(a);
        } else {
            newY = p.y + sin(a);
        }
    }
    
    p.x = newX;
    p.y = newY;

    if (!inCircle(p)) {
        p.set(randomPointInCircle());
    }
  }
}

function inCircle(v) {
  let d = dist(width/2, height/2, v.x, v.y);
  return d <= radius;
}

function inImageRect(v) {
  let halfImgWidth = img.width / 2;
  let halfImgHeight = img.height / 2;
  return v.x > (width/2 - 5 - halfImgWidth) && v.x < (width/2 - 5 + halfImgWidth) &&
         v.y > (height/2 - halfImgHeight) && v.y < (height/2 + halfImgHeight);
}

function isTransparent(x, y) {
    let pixel = img.get(floor(x - width/2 + img.width/2 + 5), floor(y - height/2 + img.height/2));
    return pixel[3] === 0;
}

function randomPointInCircle() {
  let angle = random(TAU);
  let r = sqrt(random()) * radius;
  let x = width/2 + r * cos(angle);
  let y = height/2 + r * sin(angle);
  return createVector(x, y);
}
function keyPressed() {
  // this will download the first 5 seconds of the animation!
  if (key === 's') {
    saveGif('mySketch', 50);
  }
}