Skip to content

Instantly share code, notes, and snippets.

@shshaw
Last active July 10, 2017 17:53
Show Gist options
  • Select an option

  • Save shshaw/7fa3650293185aa92bd1c7fa231f7555 to your computer and use it in GitHub Desktop.

Select an option

Save shshaw/7fa3650293185aa92bd1c7fa231f7555 to your computer and use it in GitHub Desktop.
SVG encoded for background-image
<div class="svg-bg">
<label>
<span class="svg-bg__label">Your SVG: <small>(Type or upload)</small> <div class="svg-bg__button" is="file-upload" v-on:load="loaded">Upload SVG</div></span>
<textarea class="svg-bg__input" ref="input" v-model="input">
</textarea>
</label>
<span class="svg-bg__label">background-image for CSS:
<button class="svg-bg__button" v-on:click="copy">Copy Output</button></span>
<div class="svg-bg__output" ref="output" v-html="output"></div>
</div>
<!-- SVG Background Pattern Adapted from https://github.com/progers/Patterns-Gallery -->
console.clear();
Vue.component('file-upload',{
template: `
<div class="file-upload">
<label class="file-upload__label">
<slot></slot>
<input ref="input" @change="loadFiles" accept=".svg" class="file-upload__input" type="file" />
</label>
<div class="file-upload__overlay"></div>
</div>
`,
data: ()=>({
dragging: false,
}),
// mounted(){
// document.addEventListener("dragenter", function(){ fileDrag.className = 'dragenter'; });
// document.addEventListener('dragover',function(e){ e.preventDefault(); /* Essential! */ });
// document.addEventListener("drop", FileDragDrop);
// fileDrag.addEventListener("dragleave", FileDragReset);
// },
methods:{
loadFiles(e){
e = e || window.event;
this.dragLeave(e);
var files = Array.from(e.target.files || e.dataTransfer.files || this.$ref.input.files),
len = files.length,
i = 0,
completed = [];
files.forEach((file) => {
var reader = new FileReader();
reader.onloadend = (ev)=>{
this.$emit('load', reader.result, reader, file);
//completed.push(reader.result);
//if ( completed.length >= files.length ) { this.$emit('loaded',completed); }
};
reader.readAsText(file);
//reader.readAsDataURL(file);
});
},
dragOver(e){ e.preventDefault(); /* Essential */ },
dragEnter(){ this.dragging = true },
dragLeave(e){ this.dragging = false; e.preventDefault(); },
}
});
new Vue({
el: '.svg-bg',
data: ()=>({
input: `<svg xmlns='http://www.w3.org/2000/svg' width='26' height='26' viewBox="0 0 8 8">
<circle cx="1" cy="1" r="1" opacity='0.25' />
<circle cx="5" cy="5" r="1" opacity='0.25' />
</svg>`
}),
computed: {
output(){
let url = this.encodeSVG(this.optimized);
document.body.style.backgroundImage = url;
let msg = 'background-image: ' + url + ';' +
'<br >/* SVG encoded with https://cdpn.io/rrOZQQ */';
return msg;
},
optimized(){
return this.input
.replace(/\<\?xml.+\?\>/g, '')
.replace(/(\<\!DOCTYPE(.*?)\>)/g, '')
.replace(/([\s\n]+)/g,' ');
}
},
methods: {
loaded(f){
console.log('file loaded!', typeof f, f);
this.input = f;
},
copy(){
var range = document.createRange();
range.selectNode(this.$refs.output);
window.getSelection().addRange(range);
try {
// Now that we've selected the anchor text, execute the copy command
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copy email command was ' + msg);
} catch(err) {
console.log('Oops, unable to copy');
}
// Remove the selections - NOTE: Should use
// removeRange(range) when it is supported
window.getSelection().removeAllRanges();
},
encodeSVG(svg) {
svg = svg + '';
var b64 = encodeURIComponent(svg.replace(/\<\?xml.+\?\>|\<\!DOCTYPE.+]\>/g, ''))
.replace(/%20/g," ")
.replace(/%3D/g,"=")
// Additional optimizations thanks to https://codepen.io/tigt/post/optimizing-svgs-in-data-uris
.replace(/%3A/g, ':') // ditto colons
.replace(/%2F/g, '/') // ditto slashes
.replace(/%22/g, "'"); // replace quotes with apostrophes (may break certain SVGs)
return 'url("data:image/svg+xml;charset=utf-8,'+b64+'")';
}
}
});
console.clear();
var textarea = document.querySelector('.svg-bg__input');
var code = document.querySelector('.svg-bg__output');
// Encode an SVG element as a base64 data uri.
function encodeSVG(svg) {
var b64 = encodeURIComponent(svg).replace(/%20/g," ").replace(/%3D/g,"=");
return 'url("data:image/svg+xml;charset=utf-8,'+b64+'")';
}
function update(){
var url = encodeSVG(textarea.value);
var msg =
'background-image: ' + url + ';' +
'<br >/* Encoded SVG built with https://codepen.io/shshaw/full/rrOZQQ */';
code.innerHTML = msg;
document.body.style.backgroundImage = url;
}
update();
textarea.addEventListener('keyup',update);
code.addEventListener('click',function(){
// Select the email link anchor text
var emailLink = document.querySelector('.js-emaillink');
var range = document.createRange();
range.selectNode(emailLink);
window.getSelection().addRange(range);
try {
// Now that we've selected the anchor text, execute the copy command
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copy email command was ' + msg);
} catch(err) {
console.log('Oops, unable to copy');
}
// Remove the selections - NOTE: Should use
// removeRange(range) when it is supported
window.getSelection().removeAllRanges();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.min.js"></script>
<script src="https://codepen.io/shshaw/pen/epmrgO"></script>
.svg-bg {
border: solid 4px #000;
background-color: rgba(255,255,255,.7);
padding: 2em;
width: 90%;
max-width: 800px;
> * { display: block; margin-bottom: 2em; }
:last-child { margin-bottom: 0; }
}
.svg-bg__label {
display: flex;
justify-content: space-between;
align-items: center;
font-weight: bold;
margin-bottom: 0.5em;
}
.svg-bg__button {
font-weight: 100;
border: solid 2px #000;
background: #000;
color: #FFF;
padding: 0.5em 0.75em;
cursor: pointer;
text-transform: uppercase;
font-size: 0.75em;
letter-spacing: 0.1em;
&:hover {
background: #FFF;
color: #000;
}
}
.svg-bg__input,
.svg-bg__output {
border: 2px solid #000;
background-color: rgba(255,255,255,.95);
font-family: monospace;
padding: 1%;
word-break: break-all;
box-sizing: border-box;
}
.svg-bg__input {
display: block;
width: 100%;
height: 10em;
box-sizing: border-box;
}
svg { display: none; }
* { box-sizing: border-box; }
html { width: 100%; height: 100%; }
body { min-height: 100%; display: flex; background-position: center center; }
.svg-bg { margin: auto; }
.file-upload__label {
position: relative;
overflow: hidden;
cursor: pointer;
}
.file-upload__input {
display: block;
width: 100%;
height: 100%;
cursor: pointer;
opacity: 0;
position: absolute;
top: 0;
left: 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment