🌊

Vanilla JSで作るハッカーUIパーツ集:再利用性を高める技術実装メモ

に公開

「あの時作ったあのエフェクト、どうやったっけ?」をゼロにするための自分用パーツ集。 映画のようなハッカー端末を作る過程で得た「低負荷・高効果」な実装を逆引き形式で記録する。組み込み開発におけるデバッグ画面や、軽量なWeb UIへの転用を想定。

1. 【視覚】走査線・ブラウン管エフェクト

画面全体に被せるだけで「レトロ端末」の質感を出す。

CSS
/* SCANLINE_OVERLAY: 疑似ブラウン管エフェクト */
body::before {
    content: " ";
    display: block;
    position: fixed;
    top: 0; left: 0; bottom: 0; right: 0;
    /* 4px周期で透明と黒を繰り返す */
    background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%);
    background-size: 100% 4px; 
    z-index: 10;
    pointer-events: none; /* 下層の操作を邪魔しない */
}

なぜこれで動くのか

  • 低負荷: 画像ファイルを読み込む必要がないため、ネットワーク帯域やメモリを節約できる。
  • 拡張性: 4px の値を変更すれば、解像度に応じた線の太さを調整可能。

2. 【映像】ナイトビジョン・カメラフィルタ

Webカメラ映像を「監視カメラ風」にリアルタイム加工する。

css
/* NIGHT_VISION_FILTER */
video {
    width: 100%;
    height: 100%;
    object-fit: cover; /* 枠に合わせてアスペクト比を維持しつつ埋める */
    /* セピア変換 → 色相回転(緑へ) → コントラスト強調 */
    filter: sepia(100%) hue-rotate(90deg) brightness(80%) contrast(150%);
}

なぜこれで動くのか

  1. sepia(100%) で全てのピクセルを一旦茶色の階調に落とす(色情報を一本化)。
  2. hue-rotate(90deg) でその茶色を色相環上で「緑」の位置まで回転させる。
  3. contrast でデジタル特有のパキッとした質感にする。

組み込み・再利用メモ

  • GPU活用: filter プロパティはブラウザのGPU加速が効くため、JavaScriptでピクセル操作するより圧倒的に高速。
  • 応用: hue-rotate の値を変えれば、レッドアラート(赤)やサーモグラフィ風への切り替えも容易。

3. 【制御】逐次タイピング・エンジン

文字列を1文字ずつ出力し、「処理が進んでいる感」を出す。

JavaScript
// TYPING_ENGINE: 1文字ずつ出力するシーケンス
function showTypingEffect() {
    const targetText = commandSets[setIndex].cmd;
    const char = targetText[charIndex]; 

    // 1文字追加
    const charSpan = document.createElement('span');
    charSpan.textContent = char;
    parentElement.appendChild(charSpan);
    
    charIndex++;

    // 全文字出力終了判定
    if (charIndex >= targetText.length) {
        charIndex = 0; // 次回のためにポインタを戻す
        startNextSequence(); // 次の処理へ
    }
}

なぜこれで動くのか

  • 文字列を配列として扱い、インデックス (charIndex) を1つずつ進めながらDOM要素を物理的に生成・追加していく。

組み込み・再利用メモ

  • デバッグ出力: 組み込み機器の起動ログをブラウザに流す際、一気に表示させると視認性が悪いが、この速度制御を入れることで「今何が起きているか」を追いやすくできる。

4. 【緊急】システム・クラッシュ演出

致命的なエラーが発生した際の視覚的な警告。

JavaScript
// FATAL_ERROR_UI: 視覚的な警告
function triggerCrash() {
    // 画面全体を色反転・傾斜させて違和感を出す
    document.body.style.filter = "invert(100%)";
    document.body.style.transform = "skewX(5deg)";
    
    setTimeout(() => {
        // 最終的なHALT画面(ブルースクリーン)へ
        document.body.innerHTML = `
            <div style="background:blue; color:white; height:100vh; padding:20px;">
                FATAL ERROR: REBOOT REQUIRED
            </div>`;
    }, 150);
}

なぜこれで動くのか

  • CSSの filtertransform を一瞬適用させることで、脳に「バグった」という強烈な視覚的フィードバックを与え、その直後にDOMを全消去してエラーメッセージに置き換える。

組み込み・再利用メモ

  • Watchdog連動: 異常検知時にこの関数を叩くことで、シリアルコンソールを見ていないユーザーにも即座に異常を知らせることができる。

5. 【起動】不規則ローディング・カウンター

起動画面でよく見る「0% → 100%」のプログレス表示。これを単調なインクリメントではなく、不規則な速度で上昇させることで、裏で"何か重い処理"が走っているようなリアリティを演出する。

JavaScript

// RANDOM_LOADER: 不規則な速度でカウントアップ
function startLoadingSequence() {
  const progressText = document.getElementById('progress');
  let loadPercent = 0;

  const loadInterval = setInterval(() => {
    // 毎回 2〜6% の範囲でランダムに進捗させる
    loadPercent += Math.floor(Math.random() * 5) + 2; 
    
    // 100%を超えないようにキャップをかける
    if (loadPercent > 100) loadPercent = 100;

    // 表示更新(既存のテキストがある場合は数字だけ書き換える等の工夫も可)
    if (progressText) {
      progressText.innerText = `SYSTEM BOOT... ${loadPercent}%`;
    }

    // 完了時の処理
    if (loadPercent === 100) {
      clearInterval(loadInterval);
      // ここで画面遷移やフェードアウトの関数を呼ぶ
      console.log("Boot Sequence Complete.");
    }
  }, 60); // 60msごとに更新判定
}

なぜこれで動くのか

  • Math.random() の活用: loadPercent++ のような一定の加算ではなく、ランダムな増分(+2〜+6など)を与えることで、進捗バーが「急に進んだり、少し停滞したり」する動きになり、読み込み処理の重みにばらつきがあるように錯覚させる。

  • キャップ処理: ランダム加算だと103%などになり得るため、if (loadPercent > 100) loadPercent = 100; で確実に100で止める制御が必須。

組み込み・再利用メモ

  • 演出としての待ち時間: 実際のロード時間が0秒であっても、ユーザーに「システムの重厚感」を感じさせるためにあえて導入する場合がある(UX上の演出)。

  • 実処理とのハイブリッド: 実際の初期化処理(ハードウェアチェックなど)が終わるまでは99%で止めておき、完了イベントで100%にする、といった制御に拡張すると、より実用的な「スプラッシュスクリーン」になる。

結び

これらのパーツは、それぞれ独立してコピペ利用可能。 未来の自分が「かっこいいUI」を最速で作るための武器庫として活用する。
メモに関してはGeminiに聞いたものなので実際にその場になったら検証して修正する。


検索用キーワード(自分用)

#UIパーツ #ナイトビジョン #CRTエフェクト #タイピングアニメーション #VanillaJS #デバッグ画面 #ロマン

Discussion