生成AI+スマホで作成「WordPress(ブログ)で使えるJavaScript」 「正の字」カウンター

合計: 0

コードエディター 本文

    <div class="count-display">合計: <span id="total-count">0</span>本</div>
    
    <div id="tally-container">
        </div>

    <div class="controls">
        <button id="add-btn">カウントアップ!</button>

        <button id="reset-btn">リセット</button>
    </div>

カスタムJavaScript

        let totalCount = 0;
        const container = document.getElementById('tally-container');
        const totalDisplay = document.getElementById('total-count');
        const addBtn = document.getElementById('add-btn');
        const resetBtn = document.getElementById('reset-btn');

        const strokes = [
            { x1: 20, y1: 20, x2: 80, y2: 20 }, // 1画
            { x1: 50, y1: 20, x2: 50, y2: 85 }, // 2画
            { x1: 50, y1: 50, x2: 85, y2: 50 }, // 3画
            { x1: 20, y1: 50, x2: 20, y2: 85 }, // 4画
            { x1: 10, y1: 85, x2: 90, y2: 85 }  // 5画
        ];

        function createNewKanji() {
            const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
            svg.setAttribute("viewBox", "0 0 100 100");
            svg.classList.add("kanji-box");

            strokes.forEach(s => {
                const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
                line.setAttribute("x1", s.x1); line.setAttribute("y1", s.y1);
                line.setAttribute("x2", s.x2); line.setAttribute("y2", s.y2);
                svg.appendChild(line);
            });
            container.appendChild(svg);
            return svg;
        }

        addBtn.addEventListener('click', () => {
            // 1画目、6画目、11画目... のタイミングで新しい箱を作る
            if (totalCount % 5 === 0) {
                createNewKanji();
            }

            totalCount++;
            totalDisplay.textContent = totalCount;

            const currentKanji = container.lastElementChild;
            const strokeIndex = (totalCount - 1) % 5;
            currentKanji.querySelectorAll('line')[strokeIndex].style.visibility = 'visible';
        });

        resetBtn.addEventListener('click', () => {
            if (confirm('すべてのカウントをリセットしますか?')) {
                totalCount = 0;
                totalDisplay.textContent = '0';
                container.innerHTML = ''; // 完全に空にする
            }
        }); 

カスタムCSS

        #tally-container {
            display: flex; 
            flex-wrap: wrap; 
            justify-content: flex-start; /* 確実に左寄せ */
            align-content: flex-start;
            gap: 15px; 
            width: 90%;
            max-width: 600px;
            min-height: 100px; 
            margin-bottom: 20px; 
            padding: 25px;
            background: white; 
            border-radius: 12px; 
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
        }

        .kanji-box { width: 70px; height: 70px; }
        
        line {
            stroke: #1a1a1a; 
            stroke-width: 8; 
            stroke-linecap: round;
            visibility: hidden;
        }

        .controls { text-align: center; }
        .count-display { font-size: 1.2rem; font-weight: bold; margin-bottom: 0px; color: #333; }
        
        button { 
            padding: 12px 28px; font-size: 1.1rem; cursor: pointer; border: none; 
            border-radius: 8px; margin: 0 8px; font-weight: bold; transition: opacity 0.2s;
        }
        #add-btn { background: #007AFF; color: white; }
        #reset-btn { background: #FF3B30; color: white; }
        button:hover { opacity: 0.8; }
        button:active { transform: scale(0.96); }