![svg.gif](https://qiita-image-store.s3.amazonaws.com/0/135478/1732b836-a8bd-45a2-2f45-7793a4612e8f.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;
});
}