Save an HTTP request by encoding your SVG into a Data URI for CSS background-images.
Learn more about this technique: https://codepen.io/tigt/post/optimizing-svgs-in-data-uris
| <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; | |
| } |
Save an HTTP request by encoding your SVG into a Data URI for CSS background-images.
Learn more about this technique: https://codepen.io/tigt/post/optimizing-svgs-in-data-uris