Edited at

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

More than 1 year has passed since last update.

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;
});
}