LoginSignup
14
13

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-06-21


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;
    });
}
14
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13