マトリックスレイン

カタカナや数字が緑の軌跡で流れ落ちる映画風デジタルレイン。残像合成と先頭の発光で雰囲気を出します。テック系の演出やイントロに。

#canvas#animation#text#retro

ライブデモ

使用例(お題: SaaS FlowDesk)

この技法を「SaaS FlowDesk」というテーマのダミーサイトで実際に使った例です。

HTML
<!-- FlowDesk:セキュリティ機能セクション(マトリックスレイン背景) -->
<section class="fd-sec">
  <!-- 主役:デジタルレイン背景 -->
  <canvas class="fd-sec__rain" id="fdMatrix"></canvas>

  <!-- 前景UI:セキュリティ訴求カード -->
  <div class="fd-sec__inner">
    <span class="fd-sec__tag">ENTERPRISE SECURITY</span>
    <h1 class="fd-sec__title">データは、つねに暗号化。</h1>
    <p class="fd-sec__lead">保存時・通信時ともに AES-256 / TLS1.3 で保護。SOC2 Type II 準拠の堅牢な基盤で、チームの情報を守ります。</p>

    <ul class="fd-sec__list">
      <li><span class="fd-dot"></span>エンドツーエンド暗号化</li>
      <li><span class="fd-dot"></span>シングルサインオン(SAML)</li>
      <li><span class="fd-dot"></span>監査ログ・権限管理</li>
    </ul>
    <a class="fd-sec__btn" href="#">セキュリティ詳細</a>
  </div>
</section>
CSS
/* FlowDesk:マトリックスレイン背景のセキュリティ訴求 */
:root {
  --navy: #0f1b34;
  --blue: #4f7cff;
  --white: #ffffff;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  height: 400px;
  font-family: "Hiragino Kaku Gothic ProN", "Segoe UI", system-ui, sans-serif;
  overflow: hidden;
}

.fd-sec {
  position: relative;
  height: 400px;
  overflow: hidden;
  background: linear-gradient(160deg, #0c1730, #070d1d);
}

/* 主役:流れ落ちる文字(背景) */
.fd-sec__rain {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 1;
  opacity: 0.55;
}

/* 前景UI:右からのグラデで読みやすく */
.fd-sec__inner {
  position: relative;
  z-index: 2;
  padding: 38px 32px;
  max-width: 440px;
  height: 100%;
  background: linear-gradient(90deg, rgba(10,18,38,0.92) 55%, transparent);
}
.fd-sec__tag {
  display: inline-block;
  font-size: 10px;
  letter-spacing: 0.28em;
  color: #6fe0a8;
  font-weight: 800;
}
.fd-sec__title {
  margin: 13px 0 12px;
  font-size: 26px;
  line-height: 1.4;
  font-weight: 800;
  color: var(--white);
}
.fd-sec__lead {
  margin: 0 0 18px;
  font-size: 13px;
  line-height: 1.8;
  color: rgba(255,255,255,0.76);
}

.fd-sec__list { list-style: none; margin: 0 0 22px; padding: 0; }
.fd-sec__list li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: rgba(255,255,255,0.88);
  padding: 5px 0;
}
.fd-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #6fe0a8;
  box-shadow: 0 0 10px rgba(111,224,168,0.8);
}

.fd-sec__btn {
  display: inline-block;
  padding: 11px 22px;
  border-radius: 9px;
  background: var(--blue);
  color: var(--white);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  box-shadow: 0 10px 24px rgba(79,124,255,0.4);
  transition: transform 0.2s ease;
}
.fd-sec__btn:hover { transform: translateY(-2px); }

@media (prefers-reduced-motion: reduce) {
  .fd-sec__btn { transition: none; }
}
JavaScript
// FlowDesk:マトリックスレイン(背景演出)
(() => {
  const canvas = document.getElementById('fdMatrix');
  if (!canvas) return; // null安全
  const ctx = canvas.getContext('2d');
  if (!ctx) return;

  let w = 0, h = 0, raf = 0, running = true, cols = 0, drops = [];
  const dpr = Math.min(window.devicePixelRatio || 1, 2);
  const fontSize = 14;
  // カタカナ+数字+記号
  const glyphs = 'アカサタナハマヤラワabcdef0123456789{}<>$#@'.split('');

  function resize() {
    const r = canvas.getBoundingClientRect();
    w = r.width; h = r.height;
    canvas.width = Math.max(1, w * dpr);
    canvas.height = Math.max(1, h * dpr);
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    cols = Math.floor(w / fontSize);
    // 各列の先頭位置(ランダムな開始でばらけさせる)
    drops = Array.from({ length: cols }, () => Math.random() * -h / fontSize);
  }
  resize();

  function step() {
    // 残像(軌跡を残す)
    ctx.fillStyle = 'rgba(7,13,29,0.12)';
    ctx.fillRect(0, 0, w, h);
    ctx.font = `${fontSize}px monospace`;

    for (let i = 0; i < cols; i++) {
      const ch = glyphs[Math.floor(Math.random() * glyphs.length)];
      const x = i * fontSize;
      const y = drops[i] * fontSize;
      // 先頭は明るく、それ以外は緑系
      ctx.fillStyle = '#cfffe6';
      ctx.fillText(ch, x, y);
      ctx.fillStyle = 'rgba(79,224,150,0.85)';
      ctx.fillText(glyphs[Math.floor(Math.random() * glyphs.length)], x, y - fontSize);

      // 列をリセット(ランダムで間隔をばらす)
      if (y > h && Math.random() > 0.975) drops[i] = 0;
      drops[i]++;
    }
    raf = requestAnimationFrame(step);
  }

  function start() {
    if (running) return;
    running = true;
    raf = requestAnimationFrame(step);
  }
  function stop() {
    running = false;
    cancelAnimationFrame(raf);
  }

  window.addEventListener('resize', resize);
  document.addEventListener('visibilitychange', () => {
    document.hidden ? stop() : start();
  });

  running = false;
  start();
})();

コード

HTML
<!-- マトリックスレイン -->
<div class="stage">
  <canvas id="matrixCanvas"></canvas>
</div>
CSS
/* マトリックスレイン(漆黒背景) */
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
.stage {
  position: relative;
  width: 100%;
  height: 360px;
  overflow: hidden;
  background: #000;
}
#matrixCanvas {
  display: block;
  width: 100%;
  height: 100%;
}
JavaScript
// マトリックス風デジタルレインデモ
(() => {
  const canvas = document.getElementById('matrixCanvas');
  if (!canvas) return;
  const ctx = canvas.getContext('2d');
  const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  // 描画文字(カタカナ+数字+記号)
  const glyphs = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホ0123456789@#$%&*+=<>'.split('');
  const fontSize = 16;
  let w = 0, h = 0, cols = 0, drops = [];
  const dpr = Math.min(window.devicePixelRatio || 1, 2);

  function resize() {
    const r = canvas.getBoundingClientRect();
    w = r.width; h = r.height;
    canvas.width = w * dpr;
    canvas.height = h * dpr;
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    cols = Math.ceil(w / fontSize);
    // 各列の落下位置をランダムに初期化
    drops = Array.from({ length: cols }, () => Math.random() * -h);
  }
  resize();
  window.addEventListener('resize', resize);

  function step() {
    // 残像を作るために半透明の黒で覆う
    ctx.fillStyle = 'rgba(0,0,0,0.08)';
    ctx.fillRect(0, 0, w, h);
    ctx.font = `${fontSize}px monospace`;

    for (let i = 0; i < cols; i++) {
      const ch = glyphs[(Math.random() * glyphs.length) | 0];
      const x = i * fontSize;
      const y = drops[i];
      // 先頭は明るく、後続は緑のグラデ
      ctx.fillStyle = '#cfffd6';
      ctx.fillText(ch, x, y);
      ctx.fillStyle = '#19c34a';
      ctx.fillText(ch, x, y - fontSize);

      drops[i] += fontSize * (reduced ? 0.3 : 1);
      // 下端を越えたらランダムに上へ戻す
      if (drops[i] > h && Math.random() > 0.975) drops[i] = Math.random() * -40;
    }
    requestAnimationFrame(step);
  }
  requestAnimationFrame(step);
})();

🤖 AIエージェント用プロンプト

このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「マトリックスレイン」の効果を追加してください。

# 追加してほしい効果
マトリックスレイン(Canvas エフェクト)
カタカナや数字が緑の軌跡で流れ落ちる映画風デジタルレイン。残像合成と先頭の発光で雰囲気を出します。テック系の演出やイントロに。

# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】

# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- マトリックスレイン -->
<div class="stage">
  <canvas id="matrixCanvas"></canvas>
</div>

【CSS】
/* マトリックスレイン(漆黒背景) */
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
.stage {
  position: relative;
  width: 100%;
  height: 360px;
  overflow: hidden;
  background: #000;
}
#matrixCanvas {
  display: block;
  width: 100%;
  height: 100%;
}

【JavaScript】
// マトリックス風デジタルレインデモ
(() => {
  const canvas = document.getElementById('matrixCanvas');
  if (!canvas) return;
  const ctx = canvas.getContext('2d');
  const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  // 描画文字(カタカナ+数字+記号)
  const glyphs = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホ0123456789@#$%&*+=<>'.split('');
  const fontSize = 16;
  let w = 0, h = 0, cols = 0, drops = [];
  const dpr = Math.min(window.devicePixelRatio || 1, 2);

  function resize() {
    const r = canvas.getBoundingClientRect();
    w = r.width; h = r.height;
    canvas.width = w * dpr;
    canvas.height = h * dpr;
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    cols = Math.ceil(w / fontSize);
    // 各列の落下位置をランダムに初期化
    drops = Array.from({ length: cols }, () => Math.random() * -h);
  }
  resize();
  window.addEventListener('resize', resize);

  function step() {
    // 残像を作るために半透明の黒で覆う
    ctx.fillStyle = 'rgba(0,0,0,0.08)';
    ctx.fillRect(0, 0, w, h);
    ctx.font = `${fontSize}px monospace`;

    for (let i = 0; i < cols; i++) {
      const ch = glyphs[(Math.random() * glyphs.length) | 0];
      const x = i * fontSize;
      const y = drops[i];
      // 先頭は明るく、後続は緑のグラデ
      ctx.fillStyle = '#cfffd6';
      ctx.fillText(ch, x, y);
      ctx.fillStyle = '#19c34a';
      ctx.fillText(ch, x, y - fontSize);

      drops[i] += fontSize * (reduced ? 0.3 : 1);
      // 下端を越えたらランダムに上へ戻す
      if (drops[i] > h && Math.random() > 0.975) drops[i] = Math.random() * -40;
    }
    requestAnimationFrame(step);
  }
  requestAnimationFrame(step);
})();

# 外部ライブラリ
なし(追加ライブラリ不要)

# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。