生成AI+スマホで作成「WordPress(ブログ)で使えるJavaScript」 ブログの画面に雨を降らせる

​ 「雨は、世界を洗い流す銀の針。街の喧騒を遠ざけ、心を静かな場所へと連れていく。たまには傘も差さずに、空の涙を受け止める時間があってもいい。」

コードエディター 本文

    <div class="content">
       <p id="writing">
​ 「雨は、世界を洗い流す銀の針。街の喧騒を遠ざけ、心を静かな場所へと連れていく。たまには傘も差さずに、空の涙を受け止める時間があってもいい。」
        </p>
    </div>
    <canvas id="rainCanvas"></canvas>

カスタムJavaScript

        const canvas = document.getElementById('rainCanvas');
        const ctx = canvas.getContext('2d');

        let width, height;
        let drops = [];

        // キャンバスサイズを画面に合わせる
        function resize() {
            width = canvas.width = window.innerWidth;
            height = canvas.height = window.innerHeight;
        }

        window.addEventListener('resize', resize);
        resize();

        // 雨粒の定義
        class Drop {
            constructor() {
                this.reset();
                // 初回のみy座標をランダムに散らす
                this.y = Math.random() * height;
            }

            reset() {
                this.x = Math.random() * width;
                this.y = -20; // 画面上部から開始
                this.speed = Math.random() * 15 + 10; // 落下速度
                this.length = Math.random() * 20 + 15; // 雨粒の長さ
                this.opacity = Math.random() * 0.3 + 0.1; // 透明度
                this.wind = 1; // わずかな風(右方向への流れ)
            }

            update() {
                this.y += this.speed;
                this.x += this.wind;

                // 画面外に出たらリセット
                if (this.y > height) {
                    this.reset();
                }
            }

            draw() {
                ctx.beginPath();
                ctx.strokeStyle = `rgba(180, 200, 255, ${this.opacity})`;
                ctx.lineWidth = 1;
                ctx.lineCap = 'round';
                ctx.moveTo(this.x, this.y);
                ctx.lineTo(this.x + this.wind, this.y + this.length);
                ctx.stroke();
            }
        }

        // 雨粒の生成(500個)
        function initRain() {
            drops = [];
            for (let i = 0; i < 500; i++) {
                drops.push(new Drop());
            }
        }

        // メインループ
        function animate() {
            // 背景を完全に消さず、わずかに塗りつぶすことで「残像」を作る
            ctx.clearRect(0, 0, width, height);

            drops.forEach(drop => {
                drop.update();
                drop.draw();
            });

            requestAnimationFrame(animate);
        }

        initRain();
        animate();

カスタムCSS

    /* 全体のレイアウト */
    body {
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
    }

    /* cocoon(WordPress)の特定の記事のタイトル背景色を変える */
    /* 記事のURLにあるpost idを入力する */
    .postid-111 .entry-title {
            background-color: #ffffff; /* ここに好きな色コードを入力 */
            color: #000000; /* 文字の色 */
            font-size: 1.2em; /* 文字のサイズ */
            letter-spacing: -0.02em;
        //  padding: 20px;            /* 文字の周りに余白を作る場合 */
        //  border-radius: 5px;       /* 角を丸くする場合 */
            font-family: "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Meiryo", sans-serif;
     }

    /* 背面のコンテンツ */
    .content {
            position: relative;
            z-index: 1; /* 雨より下に配置 */
            line-height: 1.8;
            pointer-events: auto; /* 文字選択やリンクを有効にする */
            width: fit-content;  /* 中身の幅に合わせる */
            margin-left: auto;   /* 左の余白を自動 */
            margin-right: auto;  /* 右の余白を自動 */
  
            /* 文字は左寄せ */
            text-align: left;
    }

    /* 背面の文章 */
    #writing {
            padding: 80px 20px;
            background-color: #0b101b;
            color: #c6c6c6;
    }

    /* 前面の雨キャンバス */
    #rainCanvas {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 10; /* 最前面に配置 */
            pointer-events: none; /* マウスイベントを透過(下の文字を触れるようにする) */
   }

   /* ソースコードの表示設定 */
   pre { 
            font-size: 0.8em; 
            /* 折り返し設定 */
            white-space: pre-wrap;       
            overflow-wrap: break-word; 
    }