Help us understand the problem. What is going on with this article?

SVGをURLエンコードし、CSSのbackground-imageプロパティの値に設定して出力するツールを公開しました。

More than 1 year has passed since last update.


svg.gif

SVGをCSSのbackground-imageで使えるようにエンコードするツール

コピペするだけで使えます。
JSでのSVGのURLエンコードはencodeURIComponent()を使う人が多いみたいですが、
それだとファイルサイズが大幅に増えてしまうので、自前で必要なものだけエンコードする形にしました。

機能

  • リアルタイムプレビュー

  • 背景色変更

  • svg以外のタグが入っていた場合、自動削除

  • ネームスペースがない場合、自動付与

  • 改行、スペース、コメントアウトを自動削除

コード

HTML
<div id="entry">

    <div id="stbic">
        <div id="stbic-forms">
            <div id="stbic-svg">
                <h2>SVG</h2>
                <textarea id="input-svg"></textarea>
            </div>

            <div id="stbic-css">
                <h2>CSS</h2>
                <textarea id="output-css"></textarea>
            </div>

        </div>

        <div id="stbic-colors">
            <input type="radio" name="color" id="white" />
            <label for="white" data-color="#fff"></label>

            <input type="radio" name="color" id="lightgrey" />
            <label for="lightgrey" data-color="#eee"></label>

            <input type="radio" name="color" id="grey" />
            <label for="grey" data-color="#999"></label>

            <input type="radio" name="color" id="black" />
            <label for="black" data-color="#000"></label>

            <input type="radio" name="color" id="pink" />
            <label for="pink" data-color="#f48fb1"></label>

            <input type="radio" name="color" id="purple" />
            <label for="purple" data-color="#b39ddb"></label>

            <input type="radio" name="color" id="blue" />
            <label for="blue" data-color="#90caf9"></label>

            <input type="radio" name="color" id="skyblue" />
            <label for="skyblue" data-color="#80deea"></label>

            <input type="radio" name="color" id="green" />
            <label for="green" data-color="#a5d6a7"></label>

            <input type="radio" name="color" id="yellowgreen" />
            <label for="yellowgreen" data-color="#e6ee9c"></label>

            <input type="radio" name="color" id="yellow" />
            <label for="yellow" data-color="#ffe082"></label>

            <input type="radio" name="color" id="orange" />
            <label for="orange" data-color="#ffab91"></label>
        </div>

    </div>

</div>
CSS
#entry {
    background-color: #fff;
    height: 600px;
    margin: 0 auto;
    width: 1235px;
}

#stbic {
    background-color: #fff;
    -webkit-box-sizing: border-box;
            box-sizing: border-box;
    height: 400px;
    margin: 0 auto;
    padding: 10px 5px;
    width: 1135px;
}

#stbic-forms {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-pack: justify;
        -ms-flex-pack: justify;
            justify-content: space-between;
}

#stbic-svg,
#stbic-css {
    -webkit-box-flex: 1;
        -ms-flex: 1;
            flex: 1;
    height: 300px;
    margin: 0 5px;
    text-align: center;
}

#stbic textarea {
    border: 2px solid #ddd;
    height: 200px;
    padding: 15px;
    width: 90%;
}

#stbic-forms textarea {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    outline: none;
}

#stbic-colors {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-pack: center;
        -ms-flex-pack: center;
            justify-content: center;
    margin-top: 30px;
}

#stbic-colors > input {
    display: none;
    margin: 0;
    padding: 0;
}

#white + label {
    border: 1px solid #ddd; 
}

input + label {
    border-radius: 50%;
    border: 2px solid transparent;
    height: 25px;
    margin: 0 7px 10px 7px;
    padding: 0;
    -webkit-transition: all .3s 0s ease;
    transition: all .3s 0s ease;
    width: 25px;
}

#stbic-colors > input:checked + label {
    height: 35px;
    -webkit-transform: translateY(-10px);
            transform: translateY(-10px);
    width: 35px;
}

#stbic-colors > label:hover {
    cursor: pointer;
}

#white + label {
    background-color: #fff;
}

#lightgrey + label {
    background-color: #eee;
}

#grey + label {
    background-color: #999;
}

#black + label {
    background-color: #000;
}

#pink + label {
    background-color: #f48fb1;
}

#purple + label {
    background-color: #b39ddb;
}

#blue + label {
    background-color: #90caf9;
}

#skyblue + label {
    background-color: #80deea;
}

#green + label {
    background-color: #a5d6a7;
}

#yellowgreen + label {
    background-color: #e6ee9c;
}

#yellow + label {
    background-color: #ffe082;
}

#orange + label {
    background-color: #ffab91;
}
JavaScript
const inputSVGForm = document.getElementById('input-svg');
const outputCSSForm = document.getElementById('output-css');
const entry = document.getElementById('entry');

// Get svg only. Remove space, linefeed, and comment.
const minify = function(input) {
    let minified = input.replace(/\r?\n|<!--.*-->/g, '');
    minified = minified.match(/<svg.+<\/svg>/);
    if (null === minified) {
        return false;
    } else {
        minified = minified[0].replace(/>\s+</g, '><');
        return minified;
    }
}

const addNamespace = function(minified) {
    if (!/http:\/\/www\.w3\.org\/2000\/svg/.test(minified)) {
        const namespaced = minified.replace( /<svg/g, "<svg xmlns='http://www.w3.org/2000/svg'" );
        return namespaced;
    } else {
        return minified;
    }
}

// URL encode
const encodeSVG = function(nameSpaced) {
    // double quote to single quote
    const singleQuoted = nameSpaced.replace(/"/g, "'");

    // URL encode
    const encoded = singleQuoted.replace(/</g, '%3C').replace(/>/g, '%3E').replace(/#/g, '%23');

    return encoded;
}

const outputCSS = function(encoded) {
    const css = 'background-image: url("data:image/svg+xml;charset=utf-8,' + encoded + '");';
    outputCSSForm.value = css;
}

const preview = function(encoded) {
    entry.style.backgroundImage = 'url("data:image/svg+xml;charset=utf-8,' + encoded + '")';
}

// If size is not specified
const resize = function(nameSpaced) {
    if (!/width=/.test(nameSpaced)) {
        entry.style.backgroundSize = '50px 50px';
    }
}

inputSVGForm.addEventListener('keyup', function() {

    setTimeout(function() {

        const minified = minify(inputSVGForm.value);

        if (!minified) return;

        const nameSpaced = addNamespace(minified);

        const encoded = encodeSVG(nameSpaced);

        outputCSS(encoded);

        preview(encoded);

        resize(nameSpaced);

    }, 100);


});

// First, checked the white button 
entry.querySelector('#white').checked = true;

// Add button event
const colorButtons = document.querySelectorAll('#stbic-colors > label');
for(let i = 0, l =  colorButtons.length; i < l; i++) {
    colorButtons[i].addEventListener('click', function() {
        entry.style.backgroundColor = this.dataset.color;
    });
}
Simmon
とにかく速いWordPressテーマ「Godios.」の作者。 公式サイト→https://godios.simmon.design/ ブログ→https://blog.simmon.design/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away