One of my resolutions for 2016 is to build a better SVG background pattern generator: those that I’m aware of are good, but they don’t exploit the richness available in the technology for making designs.
What you see above is a simple prototype that shows the range of possibilities generated from a single circle, the making of which was interesting enough to warrant an article of its own…
The Base SVG
The basic SVG, without any interactivity, consists of a <circle>
element in a <pattern>
. This circle is used once in its original position, with copies offset to the top, left, bottom and right:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" height="100%" id="linkedcircles">
<defs>
<pattern id="chainedcircles"
patternUnits="userSpaceOnUse" width="250" height="250">
<circle cx="125" cy="125" r="100"
stroke-width="2" stroke="#fff" fill="none" id="circ" />
<use xlink:href="#circ" />
<use xlink:href="#circ" transform="translate(125)"/>
<use xlink:href="#circ" transform="translate(-125)"/>
<use xlink:href="#circ" transform="translate(0 125)"/>
<use xlink:href="#circ" transform="translate(0 -125)"/>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#chainedcircles)" />
</svg>
Inserting Inline SVG Into CSS
We could use this SVG in our CSS if it was saved as a separate file and referenced in a stylesheet:
body {
min-height: 100vh;
background-color: #000;
background-image: url("circles.svg");
margin: 0;
}
However, that doesn’t allow the SVG to be dynamic. Unfortunately, we can’t yet take the SVG code, place it on the web page itself, and inline it into our CSS with a reference, unless we use Mozilla’s proposed -moz-element
:
background-image: -moz-element(#linkedcircles);
Neither can we inline the SVG code into the value:
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"… ');
Or, at least, we can’t do so with predictable results: Webkit-derived browsers will be okay with this syntax, but Firefox has a problem with carriage returns (which must be escaped), and IE won’t display the SVG at all.
Using JavaScript
A better solution for a dynamic background is to base-64 encode the entire SVG. Given the SVG as a string variable, we can encode it using the window.btoa
method, then append to the correct MIME type information and write it to the background with JavaScript:
var svgString = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" …';
window.btoa(svgString);
var url = 'data:image/svg+xml;base64,' + encodedData;
document.body.style.backgroundImage = "url("+url+")";
In the case of the prototype above, the UI elements are range
and color
inputs inside a form
with an id
of patterncontrols
. Using event delegation, any input inside this form is sent to a function:
var patternMaker = document.getElementById("patterncontrols");
patternMaker.addEventListener("input", function(e) {
svg();
})
The svg()
function reads the current values of the inputs:
function svg() {
var radius = document.getElementById("radius").value,
thickness = document.getElementById("thickness").value,
…
…and concatenates them inside a string so that central circle becomes:
<circle r="'+radius+'" stroke-width="'+thickness+'"
stroke="'+circColor+'"… >
You can see the effects of these by using the controls above. Particularly interesting is the spacing
control, which changes the translate
value for the clones of the original <circle>
element, and size
, which changes the dimensions of the <pattern>
, while always keeping the original circle in its center.
More details can be found on the associated CodePen demo; I hope to have the full web app up and running by summer next year.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/JGGpzw