daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

fuzz.ts (7796B)


      1 // The signal field — the site's signature canvas texture, shared by the home
      2 // hero and every section banner. Six pixel-sorted streak bands drifting on an
      3 // additive blend plus bright filaments, looping seamlessly every nine seconds.
      4 //
      5 // Ported from daemon-sec.xyz's FuzzField. Four things are load-bearing and
      6 // break the look if changed: the loop-global phase (so two plates on one page
      7 // stay in step), the DPR backing (at 1× the streaks are 1–2px and upscaling
      8 // blurs the pixel-sorted look), the erasure scrim, and the synchronous frame
      9 // zero (rAF never fires in a hidden tab / print / screenshot).
     10 
     11 /** Band geometry — six streaks, three hues between them. `hue` is a *slot*
     12  *  (1 = iris, 2 = foam, 3 = love), not a colour: which colour a slot resolves
     13  *  to, and how it composites, is read from CSS at draw time so the field
     14  *  follows the mode along with everything else. */
     15 const BANDS = [
     16   { cy: 0.10, ch: 0.20, hue: 1, drift: 1, cyc: 1, dens: 12 },
     17   { cy: 0.34, ch: 0.24, hue: 2, drift: -1, cyc: 2, dens: 15 },
     18   { cy: 0.22, ch: 0.14, hue: 3, drift: 2, cyc: 1, dens: 9 },
     19   { cy: 0.60, ch: 0.22, hue: 2, drift: 1, cyc: 1, dens: 13 },
     20   { cy: 0.80, ch: 0.16, hue: 1, drift: -1, cyc: 2, dens: 10 },
     21   { cy: 0.92, ch: 0.14, hue: 3, drift: 1, cyc: 2, dens: 9 },
     22 ] as const;
     23 
     24 interface Palette {
     25   blend: GlobalCompositeOperation;
     26   bands: [string, string, string];
     27   filaments: [string, string, string];
     28   gain: number;
     29 }
     30 
     31 const FALLBACK: Palette = {
     32   blend: 'lighter',
     33   bands: ['196,167,231', '156,207,216', '235,111,146'],
     34   filaments: ['224,222,244', '156,207,216', '196,167,231'],
     35   gain: 1,
     36 };
     37 
     38 /**
     39  * Resolve the palette off the canvas itself, so a plate inside a scope that
     40  * pins the night palette draws the dark field even while the page around it is
     41  * on paper. Channels come back space-separated from CSS and the 2D context
     42  * wants them comma-separated, hence the normalise.
     43  */
     44 function readPalette(cv: HTMLCanvasElement): Palette {
     45   const cs = getComputedStyle(cv);
     46   const channels = (name: string, fallback: string) => {
     47     const v = cs.getPropertyValue(name).trim();
     48     return v ? v.replace(/\s+/g, ',') : fallback;
     49   };
     50   const blend = cs.getPropertyValue('--fuzz-blend').trim();
     51   const gain = parseFloat(cs.getPropertyValue('--fuzz-gain'));
     52   return {
     53     blend: (blend || FALLBACK.blend) as GlobalCompositeOperation,
     54     bands: [
     55       channels('--fuzz-band-1', FALLBACK.bands[0]),
     56       channels('--fuzz-band-2', FALLBACK.bands[1]),
     57       channels('--fuzz-band-3', FALLBACK.bands[2]),
     58     ],
     59     filaments: [
     60       channels('--fuzz-fil-1', FALLBACK.filaments[0]),
     61       channels('--fuzz-fil-2', FALLBACK.filaments[1]),
     62       channels('--fuzz-fil-3', FALLBACK.filaments[2]),
     63     ],
     64     gain: Number.isFinite(gain) ? gain : FALLBACK.gain,
     65   };
     66 }
     67 
     68 /** One frame of the field at `phase` ∈ [0,1). Every band's drift and breathe is
     69  *  a whole number of cycles per loop, so the 9s loop seams cleanly and any two
     70  *  plates on the page stay in step. */
     71 function frame(cv: HTMLCanvasElement, phase: number, amt: number, pal: Palette): void {
     72   const host = cv.parentElement;
     73   const w = (cv.clientWidth || host?.clientWidth || 0) | 0;
     74   const h = (cv.clientHeight || host?.clientHeight || 0) | 0;
     75   if (!w || !h) return;
     76 
     77   const dpr = Math.min(2, devicePixelRatio || 1);
     78   const bw = Math.round(w * dpr);
     79   const bh = Math.round(h * dpr);
     80   if (cv.width !== bw || cv.height !== bh) { cv.width = bw; cv.height = bh; }
     81 
     82   const ctx = cv.getContext('2d');
     83   if (!ctx) return;
     84   ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
     85 
     86   const frac = (x: number) => x - Math.floor(x);
     87   const rnd = (s: number) => frac(Math.sin(s * 127.1) * 43758.5453);
     88 
     89   ctx.clearRect(0, 0, w, h);
     90   ctx.globalCompositeOperation = pal.blend;
     91 
     92   for (let bi = 0; bi < BANDS.length; bi++) {
     93     const b = BANDS[bi];
     94     const cy = b.cy * h;
     95     const ch = b.ch * h;
     96     for (let y = Math.max(0, Math.round(cy - ch)); y < Math.min(h, cy + ch); y += 2) {
     97       const fall = 1 - Math.abs(y - cy) / ch;
     98       const breathe = 0.5 + 0.5 * Math.sin(2 * Math.PI * (b.cyc * phase + y * 0.004 + bi * 0.3));
     99       const env = fall * (0.4 + 0.6 * breathe);
    100       if (env <= 0.02) continue;
    101       const n = Math.round(env * b.dens * amt);
    102       for (let i = 0; i < n; i++) {
    103         const s = y * 7.3 + i * 13.7 + bi * 101.3;
    104         const x = frac(rnd(s) + phase * b.drift) * (w + 420) - 210;
    105         const len = (18 + rnd(s + 1) * 340) * (0.4 + env);
    106         const hx = 0.22 + 0.78 * Math.pow(Math.sin(Math.PI * ((x / w) * (1 + (bi % 3)) + phase + rnd(bi * 9))), 2);
    107         const a = (0.06 + rnd(s + 2) * 0.34) * env * hx * 1.7 * pal.gain;
    108         ctx.fillStyle = `rgba(${pal.bands[b.hue - 1]},${a.toFixed(3)})`;
    109         ctx.fillRect(x, y, len, rnd(s + 3) > 0.84 ? 2 : 1);
    110       }
    111     }
    112   }
    113 
    114   for (let i = 0; i < 54; i++) {
    115     const s = i * 37.1;
    116     const y = Math.round((rnd(s) * h) / 2) * 2;
    117     const cyc = 1 + (i % 2);
    118     const x = frac(rnd(s + 5) + phase * cyc) * (w + 700) - 350;
    119     const a = (0.1 + rnd(s + 6) * 0.28) * amt * pal.gain;
    120     ctx.fillStyle = `rgba(${pal.filaments[i % 3]},${a.toFixed(3)})`;
    121     ctx.fillRect(x, y, 120 + rnd(s + 7) * 520, 1);
    122   }
    123 
    124   // Scrim by erasure: destination-out bands at top and bottom so type near the
    125   // plate edges always sits on clean ink. The percentage clamp matters — a
    126   // fixed 40px erased most of the short plates.
    127   ctx.globalCompositeOperation = 'destination-out';
    128   const solid = Math.min(40, h * 0.14);
    129   const ramp = Math.min(26, h * 0.1);
    130   ctx.fillStyle = 'rgba(0,0,0,1)';
    131   ctx.fillRect(0, 0, w, solid);
    132   ctx.fillRect(0, h - solid, w, solid);
    133   let g = ctx.createLinearGradient(0, solid, 0, solid + ramp);
    134   g.addColorStop(0, 'rgba(0,0,0,1)');
    135   g.addColorStop(1, 'rgba(0,0,0,0)');
    136   ctx.fillStyle = g;
    137   ctx.fillRect(0, solid, w, ramp);
    138   g = ctx.createLinearGradient(0, h - solid - ramp, 0, h - solid);
    139   g.addColorStop(0, 'rgba(0,0,0,0)');
    140   g.addColorStop(1, 'rgba(0,0,0,1)');
    141   ctx.fillStyle = g;
    142   ctx.fillRect(0, h - solid - ramp, w, ramp);
    143   ctx.globalCompositeOperation = 'source-over';
    144 }
    145 
    146 /** Density scale. The main site ships at 6; the constant exists for tuning. */
    147 const PRESS = 6;
    148 /** The frame reduced motion keeps as the permanent texture — mid-loop, where
    149  *  the bands are at their fullest rather than at a seam. */
    150 const STILL = 0.3;
    151 
    152 /** Bind every unbound `[data-fuzz]` canvas on the page and start its loop.
    153  *  Idempotent — a second call skips already-bound canvases, so it is safe to
    154  *  call on every `astro:page-load`. */
    155 export function initFuzz(): void {
    156   const canvases = document.querySelectorAll<HTMLCanvasElement>('[data-fuzz]:not([data-bound])');
    157   canvases.forEach((cv) => {
    158     cv.dataset.bound = '1';
    159     const amt = Math.max(0.2, PRESS / 5);
    160     const reduced = matchMedia('(prefers-reduced-motion: reduce)').matches || document.documentElement.dataset.motion === 'reduce';
    161 
    162     let pal = readPalette(cv);
    163 
    164     const still = () => frame(cv, STILL, amt, pal);
    165     frame(cv, reduced ? STILL : (performance.now() / 9000) % 1, amt, pal);
    166 
    167     const ro = new ResizeObserver(() => { if (reduced) still(); });
    168     ro.observe(cv.parentElement ?? cv);
    169 
    170     const onMode = () => { pal = readPalette(cv); if (reduced) still(); };
    171     addEventListener('daemonmodechange', onMode);
    172 
    173     let raf = 0;
    174     if (!reduced) {
    175       const loop = (now: number) => {
    176         if (!document.hidden && document.documentElement.dataset.motion !== 'reduce') frame(cv, (now / 9000) % 1, amt, pal);
    177         raf = requestAnimationFrame(loop);
    178       };
    179       raf = requestAnimationFrame(loop);
    180     }
    181 
    182     document.addEventListener('astro:before-swap', () => {
    183       cancelAnimationFrame(raf);
    184       ro.disconnect();
    185       removeEventListener('daemonmodechange', onMode);
    186     }, { once: true });
    187   });
    188 }