{"id":2818,"date":"2026-03-18T14:49:47","date_gmt":"2026-03-18T05:49:47","guid":{"rendered":"https:\/\/www.earce.biz\/?page_id=2818"},"modified":"2026-03-18T14:51:57","modified_gmt":"2026-03-18T05:51:57","slug":"svg-symbol-manager","status":"publish","type":"page","link":"https:\/\/www.earce.biz\/?page_id=2818","title":{"rendered":"[Tool] SVG Symbol Manager"},"content":{"rendered":"\n<p class=\"has-text-align-center\">&lt;&lt; This service is not communicating with the server. &gt;&gt;<\/p>\n\n\n\n<div id=\"svg-tool-container\">\n    <div id=\"drop-zone-wrapper\">\n        <div id=\"drop-zone\">\n            <p>SVG\u30d5\u30a1\u30a4\u30eb\u3092\u3053\u3053\u306b\u30c9\u30e9\u30c3\u30b0\uff06\u30c9\u30ed\u30c3\u30d7<\/p>\n            <span style=\"font-size: 12px; font-weight: normal; opacity: 0.8;\">\uff08\u8907\u6570\u30d5\u30a1\u30a4\u30eb\u306e\u4e00\u62ec\u6295\u5165\u3082OK\uff09<\/span>\n        <\/div>\n    <\/div>\n\n    <div id=\"action-bar\" style=\"display: none; margin-top: 20px; text-align: center;\">\n        <button id=\"download-btn\" class=\"wp-block-button__link\">\u30b7\u30f3\u30dc\u30eb\u30d5\u30a1\u30a4\u30eb\u3092\u66f8\u304d\u51fa\u3059 (.svg)<\/button>\n        <button id=\"clear-btn\" style=\"background: #eee; color: #333; margin-left: 10px;\" class=\"wp-block-button__link\">\u30af\u30ea\u30a2<\/button>\n    <\/div>\n    \n    <div id=\"svg-library\" style=\"display: none;\"><\/div>\n    \n    <div id=\"viewer\" class=\"preview-grid\"><\/div>\n<\/div>\n\n<style>\n    #svg-tool-container { width: 100%; margin: 20px auto; font-family: sans-serif; }\n    \n    \/* \u30c9\u30ed\u30c3\u30d7\u30be\u30fc\u30f3 *\/\n    #drop-zone-wrapper {\n        border: 2px dashed #ffffff;\n        border-radius: 12px;\n        padding: 12px;\n        transition: 0.3s;\n    }\n    #drop-zone-wrapper.dragover {\n        border-style: solid;\n        background-color: rgba(255, 255, 255, 0.1);\n    }\n    #drop-zone {\n        background-color: #ffffff;\n        border-radius: 6px;\n        padding: 50px 20px;\n        text-align: center;\n        color: #0073aa;\n        cursor: pointer;\n        font-weight: bold;\n    }\n\n    \/* \u30dc\u30bf\u30f3 *\/\n    .wp-block-button__link {\n        cursor: pointer;\n        border: none;\n        padding: 10px 20px;\n        border-radius: 5px;\n        font-weight: bold;\n        transition: 0.2s;\n    }\n    #download-btn { background-color: #0073aa; color: #fff; }\n    #download-btn:hover { background-color: #005177; }\n\n    \/* \u30b0\u30ea\u30c3\u30c9\u8868\u793a *\/\n    .preview-grid {\n        display: grid;\n        grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));\n        gap: 15px;\n        margin-top: 30px;\n    }\n    .icon-card {\n        background: #fff;\n        border: 1px solid #ddd;\n        border-radius: 8px;\n        padding: 15px;\n        text-align: center;\n        position: relative;\n    }\n    .preview-icon { width: 40px; height: 40px; fill: #333; margin-bottom: 8px; }\n    .icon-name { display: block; font-size: 10px; color: #666; word-break: break-all; font-family: monospace; }\n<\/style>\n\n<script>\n(function() {\n    const wrapper = document.getElementById('drop-zone-wrapper');\n    const viewer = document.getElementById('viewer');\n    const actionBar = document.getElementById('action-bar');\n    const downloadBtn = document.getElementById('download-btn');\n    const clearBtn = document.getElementById('clear-btn');\n\n    \/\/ \u30a2\u30a4\u30b3\u30f3\u30c7\u30fc\u30bf\u3092\u4fdd\u6301\u3059\u308b\u914d\u5217\n    let iconList = [];\n\n    \/\/ \u30c9\u30e9\u30c3\u30b0\uff06\u30c9\u30ed\u30c3\u30d7\u30a4\u30d9\u30f3\u30c8\n    wrapper.addEventListener('dragover', (e) => { e.preventDefault(); wrapper.classList.add('dragover'); });\n    wrapper.addEventListener('dragleave', () => { wrapper.classList.remove('dragover'); });\n    wrapper.addEventListener('drop', (e) => {\n        e.preventDefault();\n        wrapper.classList.remove('dragover');\n        handleFiles(e.dataTransfer.files);\n    });\n\n    async function handleFiles(files) {\n        for (let file of files) {\n            if (!file.name.endsWith('.svg')) continue;\n            const text = await file.text();\n            processSVGSource(text, file.name);\n        }\n        renderPreview();\n    }\n\n    function processSVGSource(svgText, fileName) {\n        const parser = new DOMParser();\n        const doc = parser.parseFromString(svgText, \"image\/svg+xml\");\n        const svgEl = doc.querySelector('svg');\n        if (!svgEl) return;\n\n        \/\/ \u3059\u3067\u306b <symbol> \u304c\u3042\u308b\u5834\u5408\u306f\u305d\u306e\u307e\u307e\u62bd\u51fa\u3001\u306a\u3051\u308c\u3070 <svg> \u3092 <symbol> \u5316\n        const symbols = doc.querySelectorAll('symbol');\n        if (symbols.length > 0) {\n            symbols.forEach(s => {\n                iconList.push({ id: s.id, viewBox: s.getAttribute('viewBox'), content: s.innerHTML });\n            });\n        } else {\n            \/\/ \u5358\u4f53\u306eSVG\u30d5\u30a1\u30a4\u30eb\u3092symbol\u306b\u5909\u63db\n            const id = fileName.replace('.svg', '').replace(\/[^a-z0-9-_]\/gi, '-');\n            const viewBox = svgEl.getAttribute('viewBox') || \"0 0 24 24\";\n            iconList.push({ id: id, viewBox: viewBox, content: svgEl.innerHTML });\n        }\n    }\n\n    function renderPreview() {\n        viewer.innerHTML = '';\n        if (iconList.length > 0) actionBar.style.display = 'block';\n\n        iconList.forEach((icon, index) => {\n            const card = document.createElement('div');\n            card.className = 'icon-card';\n            \n            const svgNS = \"http:\/\/www.w3.org\/2000\/svg\";\n            const svg = document.createElementNS(svgNS, 'svg');\n            svg.setAttribute('viewBox', icon.viewBox);\n            svg.setAttribute('class', 'preview-icon');\n            svg.innerHTML = icon.content; \/\/ \u76f4\u63a5\u4e2d\u8eab\u3092\u5165\u308c\u308b\uff08\u30d7\u30ec\u30d3\u30e5\u30fc\u7528\uff09\n\n            const label = document.createElement('span');\n            label.className = 'icon-name';\n            label.textContent = icon.id;\n\n            card.appendChild(svg);\n            card.appendChild(label);\n            viewer.appendChild(card);\n        });\n    }\n\n    \/\/ \u66f8\u304d\u51fa\u3057\u6a5f\u80fd\n    downloadBtn.onclick = () => {\n        let output = `<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"display: none;\">\\n`;\n        iconList.forEach(icon => {\n            output += `  <symbol id=\"${icon.id}\" viewBox=\"${icon.viewBox}\">${icon.content.trim()}<\/symbol>\\n`;\n        });\n        output += `<\/svg>`;\n\n        const blob = new Blob([output], { type: 'image\/svg+xml' });\n        const url = URL.createObjectURL(blob);\n        const a = document.createElement('a');\n        a.href = url;\n        a.download = 'symbols-sprite.svg';\n        a.click();\n        URL.revokeObjectURL(url);\n    };\n\n    clearBtn.onclick = () => {\n        iconList = [];\n        renderPreview();\n        actionBar.style.display = 'none';\n    };\n})();\n<\/script>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&lt;&lt; This service is not communicating with the server. &gt;&gt; SVG\u30d5\u30a1\u30a4\u30eb\u3092\u3053\u3053\u306b\u30c9\u30e9\u30c3\u30b0\uff06\u30c9\u30ed\u30c3\u30d7 \uff08\u8907\u6570\u30d5\u30a1\u30a4\u30eb\u306e\u4e00\u62ec\u6295\u5165\u3082OK\uff09 \u30b7\u30f3\u30dc &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.earce.biz\/?page_id=2818\" class=\"more-link\"><span class=\"screen-reader-text\">&#8220;[Tool] SVG Symbol Manager&#8221; \u306e<\/span>\u7d9a\u304d\u3092\u8aad\u3080<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":35,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2818","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.earce.biz\/index.php?rest_route=\/wp\/v2\/pages\/2818","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.earce.biz\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.earce.biz\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.earce.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.earce.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2818"}],"version-history":[{"count":8,"href":"https:\/\/www.earce.biz\/index.php?rest_route=\/wp\/v2\/pages\/2818\/revisions"}],"predecessor-version":[{"id":2826,"href":"https:\/\/www.earce.biz\/index.php?rest_route=\/wp\/v2\/pages\/2818\/revisions\/2826"}],"up":[{"embeddable":true,"href":"https:\/\/www.earce.biz\/index.php?rest_route=\/wp\/v2\/pages\/35"}],"wp:attachment":[{"href":"https:\/\/www.earce.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2818"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}