let resizeTimeout; let counter; let canvas; let w, h; let noDrawZones = []; function setup() { let parent = document.getElementById('hero-animation'); canvas = createCanvas(parent.offsetWidth, parent.offsetHeight); canvas.parent(parent); colorMode(RGB, 255, 255, 255, 1); frameRate(30); noStroke(); w = parent.offsetWidth; h = parent.offsetHeight; calculateNoDrawZones(); counter = 0; } function calculateNoDrawZones() { noDrawZones = []; const elements = document.querySelectorAll('[data-fadedistance]'); const canvasRect = canvas.elt.getBoundingClientRect(); const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize); elements.forEach(el => { const zoneRect = el.getBoundingClientRect(); const fadeValueAttr = el.getAttribute('data-fadedistance'); let finalFadeInPixels; if (fadeValueAttr && fadeValueAttr.includes('vmin')) { const vminValue = parseFloat(fadeValueAttr); finalFadeInPixels = whmin(vminValue); } else if (fadeValueAttr) { finalFadeInPixels = parseFloat(fadeValueAttr); } else { finalFadeInPixels = fadeDistance; } noDrawZones.push({ left: zoneRect.left - canvasRect.left, right: zoneRect.right - canvasRect.left, top: zoneRect.top - canvasRect.top, bottom: zoneRect.bottom - canvasRect.top, fade: finalFadeInPixels }); }); } function getOpacityModifier(x, y) { let minModifier = 1; noDrawZones.forEach(zone => { let closestX = constrain(x, zone.left, zone.right); let closestY = constrain(y, zone.top, zone.bottom); let distance = dist(x, y, closestX, closestY); let modifierForThisZone = map(distance, 0, zone.fade, 0, 1); if (modifierForThisZone < minModifier) { minModifier = modifierForThisZone; } }); return constrain(minModifier, 0, 1); } function draw() { clear(); background(255, 255, 255, 0); noiseDetail(8, 0.3); let noiseLevel = 9; let noiseScale = 0.01; let noiseStep = 0.0075; let step = 30; for (let y = (h - (floor(h / step) * step)) / 2; y <= h - ((h - (floor(h / step) * step)) / 2); y += step) { for (let x = (w - (floor(w / step) * step)) / 2; x <= w - ((w - (floor(w / step) * step)) / 2); x += step) { let nx = x * noiseScale; let ny = y * noiseScale; let nz = counter * noiseStep; let opacityModifier = getOpacityModifier(x, y); let c = ceil(noiseLevel * noise(nx, ny, nz) * opacityModifier); let dr = map(c, 4, 6, 43, 231, true); let dg = map(c, 4, 6, 45, 233, true); let db = map(c, 4, 6, 47, 235, true); if (c >= 4 && opacityModifier > 0) { stroke(dr, dg, db, 255); strokeWeight(6); point(x, y); } } } counter++; } function windowResized() { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(() => { let parent = document.getElementById('hero-animation'); w = parent.offsetWidth; h = parent.offsetHeight; resizeCanvas(w, h); calculateNoDrawZones(); draw(); }, 250); } function whmin(value) { return (Math.min(w, h) * value) / 100; }