【CSS・Javascript】ホームページ(WordPress)に雷効果を入れる方法

ホームページ、Wordpress全体に雷が鳴っているような
雷効果を入れる方法をお伝えします。

これはハロウィーン、ホラー系、ゴシック系などのサイトにおすすめです。

前提として、黒系サイトであることをおすすめします。
そして、PNG形式のよりリアルな稲妻画像の準備をお願いします。

CSS(全ページ共通のCSSに追加)

/* 全画面の稲妻エフェクトレイヤー */
.lightning {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: rgba(200, 220, 255, 0.4); /* 青白い光を半透明で */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.1s ease;
}

/* 稲妻画像を配置する要素 */
.lightning-bolt {
  position: absolute;
  width: 400px;              /* 稲妻のサイズ */
  height: 400px;
	z-index: 100000; /* 背景光より上に */
  background: url("●") no-repeat center / contain;
  opacity: 0;
  transition: opacity 0.15s ease;
}

●に稲妻画像のURLを追加します。

HTML(直前に追加)

WordPressならばfooter.phpなどに追加すると良いです。

<div class="lightning">
<div class="lightning-bolt"></div>
</div>

<script src="●"></script>

Javascriptを外部ファイルで追加している前提でjsファイルのURLを●に追加。

JavaScript(ランダムで発光)

Hiro先生は、「Simple Custom CSS and JS」というプラグインを追加して
そこから外部ファイルとして利用してます。

<script>
/**
 * 全ページで「たまに雷が光る」演出
 * - 背景は半透明の青白いフラッシュ
 * - 稲妻画像はランダムな位置・角度・スケールで一瞬表示
 * - 発生間隔はランダム(既定: 60〜120秒)
 * - prefers-reduced-motion: reduce では自動再生しない
 */
(function () {
  // ===== 設定 =====
  const CONFIG = {
    // 稲妻画像(透過PNG/SVG推奨)— 複数あればランダムで選択
    boltImages: [
      "/wp-content/uploads/2025/09/—Pngtree—purple-linear-lightning-effect-current_3916933.png",
      // "/wp-content/uploads/2025/09/lightning-bolt-2.png",
      // "/wp-content/uploads/2025/09/lightning-bolt-3.png",
    ],
    boltWidth: 600,          // 稲妻の横幅(px)
    boltHeight: 600,         // 稲妻の縦幅(px)
    minDelay: 10000,         // 次の雷までの最短(ms) 60秒
    maxDelay: 60000,        // 次の雷までの最長(ms) 120秒
    firstDelay: 3000,        // 初回発生までの待機(ms)
    bgColor: "rgba(200,220,255,0.35)", // 背景フラッシュの色(青白)
    zIndex: 99999,           // 最前面
    // 稲妻の見え方(ランダムの振れ幅)
    rotateRangeDeg: 12,      // 回転の最大角度(±deg)
    scaleMin: 0.9,           // スケール最小
    scaleMax: 1.1,           // スケール最大
    topRangePct: [10, 50],   // 稲妻の表示位置(画面の高さ)% 範囲
    leftRangePct: [10, 90],  // 稲妻の表示位置(画面の幅)% 範囲
  };

  // ユーザーが動きを抑制している場合は何もしない
  const reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  if (reduceMotion) return;

  // 既存要素があれば再利用、なければ作成
  let layer = document.querySelector('.lightning');
  if (!layer) {
    layer = document.createElement('div');
    layer.className = 'lightning';
    Object.assign(layer.style, {
      position: 'fixed',
      inset: '0',
      zIndex: String(CONFIG.zIndex),
      background: CONFIG.bgColor,
      opacity: '0',
      pointerEvents: 'none',
      transition: 'opacity 0.12s ease',
    });
    document.documentElement.appendChild(layer);
  }

  let bolt = document.querySelector('.lightning-bolt');
  if (!bolt) {
    bolt = document.createElement('div');
    bolt.className = 'lightning-bolt';
    Object.assign(bolt.style, {
      position: 'absolute',
      width: CONFIG.boltWidth + 'px',
      height: CONFIG.boltHeight + 'px',
      opacity: '0',
      transition: 'opacity 0.12s ease',
      zIndex: String(CONFIG.zIndex + 1), // 背景より前
      backgroundRepeat: 'no-repeat',
      backgroundPosition: 'center',
      backgroundSize: 'contain',
    });
    layer.appendChild(bolt);
  }

  function rand(min, max) { return Math.random() * (max - min) + min; }
  function pick(arr) { return arr[Math.floor(Math.random() * arr.length)]; }

  function scheduleNext() {
    const next = rand(CONFIG.minDelay, CONFIG.maxDelay);
    setTimeout(flash, next);
  }

function flash() {
  const burst = Math.floor(Math.random() * 2) + 2; // 2〜3回
  const gap   = 240; // 1発ごとの間隔(ms) ※220〜300の範囲で好み

  for (let i = 0; i < burst; i++) {
    setTimeout(() => {
      // --- 毎発ごとに見た目をランダムに ---
      const img = pick(CONFIG.boltImages);
      bolt.style.backgroundImage = `url("${img}")`;

      const topPct  = rand(CONFIG.topRangePct[0],  CONFIG.topRangePct[1]);
      const leftPct = rand(CONFIG.leftRangePct[0], CONFIG.leftRangePct[1]);
      const deg     = rand(-CONFIG.rotateRangeDeg, CONFIG.rotateRangeDeg).toFixed(2);
      const scale   = rand(CONFIG.scaleMin, CONFIG.scaleMax).toFixed(2);

      bolt.style.top  = topPct + '%';
      bolt.style.left = leftPct + '%';
      bolt.style.transform = `translate(-50%, -50%) rotate(${deg}deg) scale(${scale})`;

      // --- 1発分の演出:雲が光る→稲妻→余韻→消灯 ---
      layer.style.opacity = '0.5';
      setTimeout(() => { bolt.style.opacity = '1';    },  80);
      setTimeout(() => { layer.style.opacity = '0.25';}, 140);
      setTimeout(() => { layer.style.opacity = '0.45';}, 220);
      setTimeout(() => { bolt.style.opacity = '0';    }, 300);
      setTimeout(() => { layer.style.opacity = '0.08';}, 360);
      setTimeout(() => { layer.style.opacity = '0';   }, 520);
    }, i * gap);
  }

    // 次回予約
    scheduleNext();
  }

  // グローバルから手動トリガーできるように
  window.flashLightning = flash;

  // 初回発生
  setTimeout(flash, CONFIG.firstDelay);
})();
</script>

是非、お試しください。