<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:media="http://search.yahoo.com/mrss/"
	
	>

<channel>
	<title>hen.bar</title>
	<link>https://hen.bar</link>
	<description>hen.bar</description>
	<pubDate>Thu, 02 Apr 2026 22:38:40 +0000</pubDate>
	<generator>https://hen.bar</generator>
	<language>en</language>
	
		
	<item>
		<title>index</title>
				
		<link>https://hen.bar/index</link>

		<pubDate>Thu, 02 Apr 2026 22:38:40 +0000</pubDate>

		<dc:creator>hen.bar</dc:creator>

		<guid isPermaLink="true">https://hen.bar/index</guid>

		<description>
	hen.ry&#38;nbsp;.barbera
&#38;nbsp;

	information
	
  work
  
    client projects
    
    playground
 




html, body {
    overflow: hidden !important;
    height: 100% !important;
}



(function () {

  // ---- PASTEL COLOR GENERATOR ----
  function randomPastelRGB() {
    const r = Math.floor(Math.random() * 127 + 127);
    const g = Math.floor(Math.random() * 127 + 127);
    const b = Math.floor(Math.random() * 127 + 127);
    return `${r},${g},${b}`;
  }

  // Each page load gets a unique pastel color
  const COLOR = randomPastelRGB();

  // CONFIG
  const LIFESPAN = 900;
  const WIDTH = 6;
  const SMOOTHING = 0.25;
  const SPACING = 1.8;

  // CANVAS
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  Object.assign(canvas.style, {
    position: "fixed",
    left: 0,
    top: 0,
    width: "100%",
    height: "100%",
    pointerEvents: "none",
    zIndex: 2147483647
  });
  document.body.appendChild(canvas);

  let dpr = window.devicePixelRatio &#124;&#124; 1;
  function resize() {
    dpr = window.devicePixelRatio &#124;&#124; 1;
    canvas.width = innerWidth * dpr;
    canvas.height = innerHeight * dpr;
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
  }
  resize();
  window.addEventListener("resize", resize);

  // POINT DATA
  let raw = [];
  let lastX = null, lastY = null;

  function smooth(x, y) {
    if (lastX === null) { lastX = x; lastY = y; return { x, y }; }
    lastX += (x - lastX) * SMOOTHING;
    lastY += (y - lastY) * SMOOTHING;
    return { x: lastX, y: lastY };
  }

  function resample(points, spacing) {
    if (points.length &#60; 2) return points;
    const out = [points[0]];
    for (let i = 1; i &#60; points.length; i++) {
      const p0 = out[out.length - 1];
      const p1 = points[i];
      const dx = p1.x - p0.x;
      const dy = p1.y - p0.y;
      const dist = Math.hypot(dx, dy);

      if (dist &#62;= spacing) {
        const steps = Math.floor(dist / spacing);
        const stepX = (dx / dist) * spacing;
        const stepY = (dy / dist) * spacing;
        for (let s = 1; s  {
    const sm = smooth(e.clientX, e.clientY);
    sm.t = performance.now();
    raw.push(sm);
  });

  window.addEventListener("pointerleave", () =&#62; {
    raw = [];
    lastX = lastY = null;
  });

  // DRAW LOOP
  function draw() {
    requestAnimationFrame(draw);
    const now = performance.now();

    raw = raw.filter(p =&#62; now - p.t &#60; LIFESPAN);

    if (raw.length &#60; 4) {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      return;
    }

    const pts = resample(raw, SPACING);
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    ctx.lineCap = "round";
    ctx.lineJoin = "round";
    ctx.lineWidth = WIDTH;

    for (let i = 1; i &#60; pts.length - 2; i++) {
      const p0 = pts[i - 1];
      const p1 = pts[i];
      const p2 = pts[i + 1];
      const p3 = pts[i + 2];

      let alpha = 1 - (now - p1.t) / LIFESPAN;
      if (alpha &#60; 0) alpha = 0;
      alpha = alpha * alpha;

      ctx.strokeStyle = `rgba(${COLOR}, ${alpha})`;

      const [cp1x, cp1y, cp2x, cp2y] = catmullRomToBezier(p0, p1, p2, p3);

      ctx.beginPath();
      ctx.moveTo(p1.x, p1.y);
      ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, p2.x, p2.y);
      ctx.stroke();
    }
  }

  draw();
})();
</description>
		
	</item>
		
	</channel>
</rss>