Components / KATAYABURI / Kata Rain

Kata Rain beta

Katakana rain: columns of falling glyphs over a black sky, because this library would.

Preview
<div class="k-rain" data-rain role="img" aria-label="Katakana rain over a black sky">
  <canvas aria-hidden="true"></canvas>
</div>
/* KATA Kata Rain — KATAYABURI. It rains katakana here. */
.k-rain{position:relative;width:100%;background:var(--k-zinc-950);border-radius:14px;overflow:hidden;font-family:var(--k-font)}
.k-rain canvas{display:block;width:100%;height:250px}
.k-rain-in{position:relative;z-index:2;padding:20px 22px}
// KATA Kata Rain — columns of falling glyphs, taupe sky optional.
document.querySelectorAll('[data-rain]').forEach(function (stage) {
  var canvas = stage.querySelector('canvas');
  var ctx = canvas.getContext('2d');
  var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  var GLYPHS = 'アカサタナハマヤラワイキシチニヒミリヲ0123456789';
  var W, H, cols, drops;
  var accent = getComputedStyle(stage).getPropertyValue('--k-accent').trim() || '#0e9594';
  function size() {
    W = canvas.clientWidth; H = canvas.clientHeight;
    canvas.width = W; canvas.height = H;
    cols = Math.floor(W / 17);
    drops = [];
    for (var i = 0; i < cols; i++) drops.push({ y: Math.random() * -40, speed: .5 + Math.random() * 1.1 });
    ctx.fillStyle = '#09090b';
    ctx.fillRect(0, 0, W, H);
  }
  function draw() {
    ctx.fillStyle = 'rgba(9,9,11,.16)';
    ctx.fillRect(0, 0, W, H);
    ctx.font = '15px monospace';
    for (var i = 0; i < cols; i++) {
      var d = drops[i];
      var ch = GLYPHS[Math.floor(Math.random() * GLYPHS.length)];
      ctx.fillStyle = accent;
      ctx.fillText(ch, i * 17 + 2, d.y * 17);
      ctx.fillStyle = 'rgba(212,212,216,.5)';
      ctx.fillText(GLYPHS[Math.floor(Math.random() * GLYPHS.length)], i * 17 + 2, (d.y - 1) * 17);
      d.y += d.speed;
      if (d.y * 17 > H && Math.random() > .978) { d.y = Math.random() * -12; d.speed = .5 + Math.random() * 1.1; }
    }
  }
  size();
  window.addEventListener('resize', size);
  if (reduced) { for (var k = 0; k < 26; k++) draw(); }
  else { setInterval(draw, 52); }
});

Installation

CLI

node kata-ui.mjs add kata-rain

Writes the part’s CSS and JS into your project. New to the CLI? See the CLI doc.

Manual

  1. Load tokens.css once, before any part.
  2. Copy the CSS tab into your stylesheet.
  3. Copy the HTML where it belongs. The part has a script — include it after the markup; it initializes itself.

Usage

A decorative downpour for the pages that can take it — launches, easter eggs, the 404 with a sense of humor. The glyphs are katakana and digits, the heads burn accent-bright, and the trails fade the way rain does. On any page doing actual business, this is the whole budget of mischief, spent at once.

Accessibility

Canvas only, aria-hidden, behind real content with real contrast. Under prefers-reduced-motion one frozen frame stands instead of the rain — the sky, holding its breath.

Anatomy

The public surface of this part, read from its own source. Class names are the API — the CSS tab above is the full contract.

.k-rainclass
.k-rain-inclass
data-raindata hook
aria-labelARIA
aria-hiddenARIA

Related parts