I'm a web developer specialising in front-end solutions combining clean coding with intuitive user interfaces and striking design approaches. I'm moving into the sector from a background in graphic design. I'm looking for junior web development roles where I can contribute from the outset with my strong creative problem solving skills, while also building my knowledge and experience of the sector. You can view some of my sample projects here, and read more about my work on my coding blog.

A semi-random pattern generator (part 1)

18 Aug 2022

Need a pattern for a design project you’re working on? Need it quick? LitPattern is a webapp generating repeating patterns using typographic characters. I built LitPattern in JavaScript using some lesser known properties of svg graphics to create repeating pattern swatches which can be downloaded as vector graphics or embedded into a webpage as css styling. This post is the first part of my write-up, covering the project backgrpund and some initial experiments.

There are lots of pattern generators online; here’s an example of a really nice one, which lets you export your artwork as svg graphics for use in your design work. Here’s something similar; this tool generates simple graphic elements.

I’ve always wanted to have a go at building a pattern generator which can create designs using typographic characters, and having recently used variable fonts in a project, I thought it would be really interesting to combine the two. With variable fonts, parameters like character weight can be continuously adjusted using CSS:

Platypus

Value: 50

Why not use characters from one of these variable fonts as elements in a pattern, and make these adjustable characteristics into parameters to help create different pattern designs?

How could this work? Well. let’s start with a simple character like “—”, the classic em dash. In the image below, I’ve started with a plain grid of em dashes, and created three new patterns just by applying some form of rotation to them. Initially, we’ve rotated all the characters by the same value so they lie on a diagonal; then, we’ve randomly rotated each character by either 0 or 90 degrees, to create an interesting maze-like figure; finally, we’ve gone full random, rotating each character by its own arbitrary amount for an effect which looks a bit like ice cream sprinkles.

This is already starting to look quite cool. I really like the simplicity of using typographic characters as graphic elements, particularly simple symbols like +, -, O, and ~ . Even simple manipulations can create striking patterns, and we quickly forget we’re looking at type. Wouldn’t it be nice to have a character input which allows you to apply these sorts of transformations on any character? What would it look like if we used symbols like A, & or $ in these designs? What other parameters can we build into our pattern generator to give us even more flexibility?

Planning it out

Let’s start planning out the objectives for this project:

  1. We need some method of generating patterns using typographic characters - this will require some kind of character input and some way to adjust parameters on these characters.

  2. Some of the following variables as parameters for the pattern generator:

Character spacing Character orientation Character weight (i.e. thickness) Character colour Character size Background colour

  1. Some method of creating a repeating pattern from these designs

  2. Some method of downloading the designs in a useful graphics format

  3. Some method of generating css from the designs so they can be used as background textures in web pages

For now, I’m looking at the first two objectives. I think it’s worth hacking together a working program as a proof of concept just to see whether this approach can work. After this, I’ll tackle point 3 and 4, which are concerned with creating a genuinely useful output from the program.

First attempt

You can have a look at my first pattern generator here. This version has absolutely not been tested for full compatibility across different devices and browsers, but it should run fine on a desktop device with Chrome. Pretty interesting right? Here are some patterns I made with this tool:

Building the grid

So do we build this? First of all, I’m going to define a space for my pattern swatch. I’ll create the gridContainer div element and set its height and width to 600px. I’ll style it with the following CSS:

#gridContainer {
  display: grid;
  align-items: center;
  justify-content: center;
  grid-template: repeat(20, 50px) / repeat(20, 50px);
  position: relative;
  overflow: hidden;
}

This creates a 20x20 grid, which I can populate with characters to form my basic pattern element. I’ve chosen a large grid because I want to allow for patterns with a lot of elements in them. I’m also going to build in functionality which allows the characters to be scaled, so I want to ensure that the grid is always big enough to fill the whole container even if the elements are close together. By setting overflow-hiddden I’m ensuring that any elements that don’t fit into the container are kept out of sight.

My full grid is going to contain 400 cells (20x20), and I’ll need to add an element to each of these. I don’t want to write that all out in html, so I’ll use this script to help me:

for (let i=0; i<400; i++){
  const para = document.createElement("div");
  para.className = "gridItem";
  para.setAttribute("id", "cell"+i);

  const node = document.createTextNode("—");
  para.appendChild(node);

  const container = document.getElementById("gridContainer");
  container.appendChild(para);   
}

This loop will build each element, using setAttribute() to add the classname gridItem and the id cell[i] every time one of these elements is created.We can use appendChild() to add text to each of these elements, and again to add each element to the gridContainer .

Adjusting the elements

I set overflow-hidden on the container, with the idea that the 20x20 grid ought be big enough to fill it when the grid spacing and font size are set really low.

For the sake of experimentation (and because it’s fun), I built as many variables into the pattern generator as I could think of. It can produce some completely wild designs! Try the prototype here:

I’ve created several sliders, which adjust css attributes to manipulate the text inside each cell using event listeners. The parameters in this prototype (with the associated css property in brackets) are font size (font-size), font weight (font-weight), drop shadow (text-shadow), rotation (transform: rotate(...)), stretching (transform: stretch(...)), spacing (grid-template - applied to the container rather than the cells), and a special parameter, jitter.

The jitter function is pretty fun, and adds an adjustable level of randomness to the positioning of the elements in the grid. The randomMultiplier() function adjusts the position of each grid item by passing a random number multiplied by the value on the input slider into the margin attribute in the stylesheet. The higher the slider value, the bigger the adjustment:

for (const item of gridItems){
  const randomMultiplier = function() {
    let plusOrMinus = Math.random() > 0.5 ? 1 : -1;
    return 0.5 * Math.random() * plusOrMinus;
  }
  item.style.margin = "0 0" + this.value*randomMultiplier() + "px " + this.value*randomMultiplier() + "px";
}

I also built in the option of adjusting the alignment of the individual elements to one of four settings: regular (every element is rotated 0 degrees) alternating (every second element is rotated 90 degrees); random (every element has a random amount of rotation applied); right angles (elements are rotated either 90 degrees or 0 degrees at random).

Finally, I added a blend mode selector, which uses the mix-blend-mode css attribute to apply a blend style from a predefined list:

let blends = ["normal", "multiply", "hard-light", "soft-light", "difference", "screen", "overlay", "color"];

That’s a lot of options! This makes the pattern generator seriously enjoyable to play with, but it’s also useful for testing which parameters help to make genuinely interesting patterns and which are too gimmicky to be of serious use.

I’ve also used this proof of concept as a testing ground for a couple of libraries - a custom colour picker with a built in alpha channel, and a “screenshot” tool which saves the pattern swatch as a png image.

Summing up

The basic concept of using text characters to create patterns is working really well here, and the idea of using a grid as a basis for each design is proving effective. I’ve got great results from this tool, but human intervention is a must at this stage to select out the small subset of designs that actually look nice and might be useful in a design project. It’s far easier to generate insane results, which are very cool to look at, but essentially useless (except maybe as NFT art?).

However, we still don’t have a way to make a repeating pattern, and we have no way of exporting our design, except as a png tile. Really, we need the design to be available in some useful format for designers, so vector graphics are a must.

Coming up next

In part 2, I’ll look at how this same project can be rebuilt using svg graphics instead of css.