<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Checkboxes on bradleycarey.com</title>
    <link>https://bradleycarey.com/tags/checkboxes/</link>
    <description>Recent content in Checkboxes on bradleycarey.com</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Wed, 18 Mar 2026 00:17:57 -0400</lastBuildDate>
    <atom:link href="https://bradleycarey.com/tags/checkboxes/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Checkbox Canvas: Images &amp; Video</title>
      <link>https://bradleycarey.com/posts/checkbox-images-and-video/</link>
      <pubDate>Tue, 17 Mar 2026 10:15:00 -0500</pubDate>
      <guid>https://bradleycarey.com/posts/checkbox-images-and-video/</guid>
      <description>&lt;p&gt;These two demos are the only ones in the series that process external input. One takes images, one takes live video. They&amp;rsquo;re also the only ones where a canvas element sneaks into the pipeline. The output still goes entirely to checkboxes; the canvas is just the fastest way to sample pixel data from a source that the browser won&amp;rsquo;t otherwise let you read directly.&lt;/p&gt;&#xA;&lt;p&gt;The underlying algorithm in both cases is the same: &lt;a href=&#34;https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Floyd-Steinberg error diffusion&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Checkbox Canvas: Games</title>
      <link>https://bradleycarey.com/posts/checkbox-games/</link>
      <pubDate>Mon, 16 Mar 2026 21:00:00 -0500</pubDate>
      <guid>https://bradleycarey.com/posts/checkbox-games/</guid>
      <description>&lt;p&gt;Games are an interesting stress test for the 1-bit constraint. A simulation can skip frames and still look fine. A game can&amp;rsquo;t. Input latency matters, collision detection matters, and the player is paying close attention in a way that they aren&amp;rsquo;t when watching a visual effect. If the game loop is wrong, you notice immediately.&lt;/p&gt;&#xA;&lt;p&gt;Both of these work. Unironically.&lt;/p&gt;&#xA;&lt;h2 id=&#34;pong-interactive&#34;&gt;&#xA;  &lt;strong&gt;&lt;a href=&#34;https://bradleycarey.com/checkboxes/pong.html&#34; &gt;Pong&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;(interactive)&lt;/em&gt;&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#pong-interactive&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Two players. Left paddle: W and S. Right paddle: up and down arrow keys.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Checkbox Canvas: Visual Effects</title>
      <link>https://bradleycarey.com/posts/checkbox-visual-effects/</link>
      <pubDate>Mon, 16 Mar 2026 10:30:00 -0500</pubDate>
      <guid>https://bradleycarey.com/posts/checkbox-visual-effects/</guid>
      <description>&lt;p&gt;Every effect here is the same underlying structure: for each checkbox, compute a number, threshold it to on/off. The interesting part is what function you use to compute the number. Pure math, no textures, no precomputed lookup tables, just trig per cell per frame.&lt;/p&gt;&#xA;&lt;div style=&#34;margin:1.5rem 0&#34;&gt;&#xA;&lt;div id=&#34;spiral-grid&#34; style=&#34;display:grid;width:fit-content;line-height:0&#34;&gt;&lt;/div&gt;&#xA;&lt;script&gt;&#xA;(function() {&#xA;  var COLS = 52, ROWS = 20;&#xA;  var g = document.getElementById(&#39;spiral-grid&#39;);&#xA;  g.style.gridTemplateColumns = &#39;repeat(&#39; + COLS + &#39;, auto)&#39;;&#xA;  var frag = document.createDocumentFragment();&#xA;  for (var i = 0; i &lt; COLS * ROWS; i++) {&#xA;    var cb = document.createElement(&#39;input&#39;);&#xA;    cb.type = &#39;checkbox&#39;;&#xA;    cb.style.pointerEvents = &#39;none&#39;;&#xA;    cb.style.cursor = &#39;default&#39;;&#xA;    frag.appendChild(cb);&#xA;  }&#xA;  g.appendChild(frag);&#xA;  var cbs = Array.from(g.querySelectorAll(&#39;input&#39;));&#xA;  var cx = COLS / 2, cy = ROWS / 2, t = 0;&#xA;  function tick() {&#xA;    t += 0.03;&#xA;    for (var r = 0; r &lt; ROWS; r++) {&#xA;      for (var c = 0; c &lt; COLS; c++) {&#xA;        var dx = c - cx, dy = (r - cy) * 1.6;&#xA;        var dist = Math.sqrt(dx * dx + dy * dy);&#xA;        var angle = Math.atan2(dy, dx);&#xA;        cbs[r * COLS + c].checked = Math.sin(angle * 3 + Math.log(dist + 1) * 4 - t * 3) &gt; 0;&#xA;      }&#xA;    }&#xA;    requestAnimationFrame(tick);&#xA;  }&#xA;  tick();&#xA;})();&#xA;&lt;/script&gt;&#xA;&lt;/div&gt;&#xA;&lt;h2 id=&#34;spirals&#34;&gt;&#xA;  &lt;strong&gt;&lt;a href=&#34;https://bradleycarey.com/checkboxes/spirals.html&#34; &gt;Spirals&lt;/a&gt;&lt;/strong&gt;&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#spirals&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Four modes that cycle automatically:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Checkbox Canvas: Simulations</title>
      <link>https://bradleycarey.com/posts/checkbox-simulations/</link>
      <pubDate>Sun, 15 Mar 2026 19:45:00 -0500</pubDate>
      <guid>https://bradleycarey.com/posts/checkbox-simulations/</guid>
      <description>&lt;p&gt;The 1-bit constraint is most interesting when you stack it against a system with real state. These four demos are simulations. They evolve by rules, and the checkboxes just report what happened. The display isn&amp;rsquo;t the computation; it&amp;rsquo;s the readout.&lt;/p&gt;&#xA;&lt;h2 id=&#34;slime-mold-simulation-interactive&#34;&gt;&#xA;  &lt;strong&gt;&lt;a href=&#34;https://bradleycarey.com/checkboxes/slime-mold-simulation.html&#34; &gt;Slime Mold Simulation&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;(interactive)&lt;/em&gt;&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#slime-mold-simulation-interactive&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Physarum_polycephalum&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Physarum polycephalum&lt;/a&gt; is a slime mold that navigated mazes, solved the shortest path between oat flakes, and independently approximated the Tokyo subway network. It has no brain, no neurons, no central coordination. Researchers at Hokkaido University published &lt;a href=&#34;https://doi.org/10.1126/science.1177894&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;a paper about it in Science in 2010&lt;/a&gt; and everyone was appropriately unsettled.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Checkbox Canvas</title>
      <link>https://bradleycarey.com/posts/checkbox-canvas/</link>
      <pubDate>Sun, 15 Mar 2026 12:00:00 -0500</pubDate>
      <guid>https://bradleycarey.com/posts/checkbox-canvas/</guid>
      <description>&lt;div id=&#34;cb-hero&#34;&gt;&#xA;&lt;style&gt;&#xA;#cb-hero { margin: 1.5rem 0; }&#xA;#cb-hero-grid { display: grid; width: fit-content; line-height: 0; }&#xA;#cb-hero-grid input { pointer-events: none; cursor: default; }&#xA;&lt;/style&gt;&#xA;&lt;div id=&#34;cb-hero-grid&#34;&gt;&lt;/div&gt;&#xA;&lt;script&gt;&#xA;(function() {&#xA;  const COLS = 24, ROWS = 8;&#xA;  const g = document.getElementById(&#39;cb-hero-grid&#39;);&#xA;  g.style.gridTemplateColumns = `repeat(${COLS}, auto)`;&#xA;  const frag = document.createDocumentFragment();&#xA;  for (let i = 0; i &lt; COLS * ROWS; i++) {&#xA;    const cb = document.createElement(&#39;input&#39;);&#xA;    cb.type = &#39;checkbox&#39;;&#xA;    frag.appendChild(cb);&#xA;  }&#xA;  g.appendChild(frag);&#xA;  const cbs = Array.from(g.querySelectorAll(&#39;input&#39;));&#xA;  let t = 0;&#xA;  function tick() {&#xA;    t += 0.07;&#xA;    for (let c = 0; c &lt; COLS; c++) {&#xA;      const h = Math.round((ROWS - 1) * (0.5 + 0.45 * Math.sin(t + c * 0.55)));&#xA;      for (let r = 0; r &lt; ROWS; r++) {&#xA;        cbs[r * COLS + c].checked = (ROWS - 1 - r) &lt;= h;&#xA;      }&#xA;    }&#xA;    requestAnimationFrame(tick);&#xA;  }&#xA;  tick();&#xA;})();&#xA;&lt;/script&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;At some point I asked myself: how bad of an idea is it to use HTML checkboxes as pixels?&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
