One of my resolutions for 2016 is to build a better 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 :

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