Quick Overview

Basic example

On this first example we will try to replicate the style of lettering generally used in classic punk rock design. To do so, we will create a ruleset that will pick a font randomly from a list of fonts, rotate the letter randomly from -7 to 7 degrees and scale it horizontally randomly by -10% to 10%. Each letter will have a 1/3 chance of being uppercase and 2/3 of being lowercase. Since the ruleset uses randomization heavily, it will produce a different result on each page load (you can try this by reloading the page).

Nevermind the Bollocks, here's generativeText!

var rules = {
    fontFamily: {
        values: [
            "'Slabo+13px'",
            "'Roboto'",
            "'Oswald'",
            "'Lora'",
            "'Bitter'",
            "'Arvo'",
            "'Anton'",
            "'Fjalla One'",
            "'Playfair Display'",
            "'Pathway Gothic One'",
            "'Bangers'",
            "'Denk One'",
            "'Alike Angular'",
            "'Source Code Pro'",
        ]
    },
    transformRotate: {
        min: -7,
        max: 7,
    },
    transformScaleX: {
        min: 0.9,
        max: 1.1,
    },
    textTransform: {
        values: ["lowercase", "lowercase", "uppercase"]
    }
};

var opts = {
    split: "wrapped",
    textSpaces: "nostyleorwrap",
}

var ransomNote = new generativeText(rules, opts);
ransomNote.applyToElementById("example1");
            

<div id="example1">Nevermind the Bollocks, here's generativeText!</div>
            

Reusing the generativeText Object

Once you have created and configured a generativeText object you can apply it to as many HTML elements as you want.

generativeText!

The preceding h4 has class "example2".

So does this one!

In fact, ALL h4s on this div have that class.

This one does too!

The other thing is that we are reusing the object and rules from the previous example.

Ain't that neat!


//We are reusing the generativeText object from the previous example
ransomNote.applyToElementsByClassName("example2");
            

<h4 class="example2">generativeText!</h4>
<p>The preceding h4 has class "example2".</p>
<h4 class="example2">So does this one!</h4>
<p>In fact, ALL h4s on this div have that class.</p>
<h4 class="example2">This one does too!</h4>
<p>The other thing is that we are reusing the object and ruleeters from the previous example.</p>
<h4 class="example2">Ain't that neat!</h4>
            

Splitting by words and using steps

generativeText objects can be configured with a variety of options. For example you can set generativeText to apply the changes to the words of the element instead of it's letters. You can also combine many rules together, have rules that are applied sequentially and combine the generated CSS rules with general CSS rules.

This reminds me of 90's wired mag.

var rules2 = {
    backgroundColor: {
        values: [
            '#ca3a11',
            '#333333',
        ],
        steps:true,
    },
    color: {
        values: [
            '#333333',
            '#ca3a11',
        ],
        steps:true;
    }
};

var opts2 = {
    split: "words",
    textSpaces: 'all',
}

var wired = new generativeText(rules2, opts2);
wired.applyToElementById("example3");
            

<div id="example3">This reminds me of 90's wired mag.</div>
            

#example3 span {
    padding: 0.16em;
    font-family: 'arvo';
    margin-bottom: 0.18em;
}

            

Numeric Rules

Certain CSS properties you can access with generativeText may take numeric parameters.

The complexity of modern CSS makes me feel so small.

var rules4 = {
    fontSize: {
        min: 3.2,
        max: 0.1,
        steps:true,
        unit: "em",
    },
};

var diminish = new generativeText(rules4);
diminish.applyToElementById("example4");
            

<div id="example4">The complexity of modern CSS makes me feel so small.</div>
            

Using step Functions

generativeText is really flexible and allows you to define yor own functions to be applied on each step.

This text will bend to a cool and wierd shape. I'm also adding some more text to show you how words break up when using the default option of split text, we'll see how to fix this on the next example.

var rules5 = {
    fontSize: {
        unit:'em',
        min:0.3,
        max:1.4,
        stepFunction: function () {
            var period = 25.1;
            var step = (period * 4) / this.totalSteps;
            var x = step * this.currentStep;
            var val = Math.abs( Math.cos(x) + (Math.cos( x/4 ) * 2) ) / 3;
            return this.min + (this.range * val);
        }
    }
};

var bend = new generativeText(rules5);
bend.applyToElementById("example5");
            

<div id="example5">This text will bend to a cool and wierd shape. I'm also adding
some more text to show you how words break up when using the default option of split text,
we'll see how to fix this on the next example.</div>


            

#example5 { font-family: 'Anton' }
            

Color Rules and Apply to "Wrapped"

generativeText also works on color Rules. And if you want to have your line breaks to not occur in the middle of a word you can use the "wrapped" split option.

Usually used in reference to a computer application, a text-based application is one whose primary input and output are based on text rather than graphics or sound. This does not mean that text-based applications do not have graphics or sound, just that the graphics or sound are secondary to the text.

var rules6 = {
    color: {
        r: {
            min: '00',
            max: 'aa',
            steps: true
        },
        g: {
            min: '00',
            max: 'aa',
            steps: true
        },
        b: {
            min: '66',
            max: 'aa',
            steps: true
        }
    }
};

var opts6 = {
    split: "wrapped",
};

var colorDegradeWrapped = new generativeText(rules6, opts6);
colorDegradeWrapped.applyToElementById("example6");
            

<div id="example6">Usually used in reference to a computer application, a text-based
application is one whose primary input and output are based on text rather than graphics or
sound. This does not mean that text-based applications do not have graphics or sound, just
that the graphics or sound are secondary to the text.</div>

            

#example6 { font-family: 'Pathway Gothic One' }
            

Pre and Pos Functions

generativeText also gives you the option of using a specific function before or after each step. This are called pfunctions and have access to a lot of variables from within generativeText. This can be used for chaining conditional rules when using random rules. In this example, we use a posFunction that selects the color of the text to be different than the randomly selected background color.

Happy Birthday!

var rules7 = {
    backgroundColor: {
        values: ['bb3030', '30bb30', '3030bb', 'eeeeee'],
    },
};


var conditionalColor = {

    values: ['ee3030', '30ee30', '3030ee', 'eeeeee'],

    posFunc: function() {

        var current = this.memory[ this.currentStep ];
        if(!!current.style) {
            var bgColor = current.style.backgroundColor;
            var rand = Math.round(Math.random() * 2);
            switch(bgColor) {
                case "rgb(187, 48, 48)":
                    var key = 1 + rand;
                    break;
                case "rgb(48, 187, 48)":
                    var key = (2 + rand) % 4;
                    break;
                case "rgb(48, 48, 187)":
                    var key = (3 + rand) % 4;
                    break;
                case "rgb(238, 238, 238)":
                    var key = rand;
                    break;
            }
            current.style.color = "#" + this.values[ key ];
        }
    }
};

var opts7 = {
    textSpaces: "nostyleorwrap",
    pObj: conditionalColor,
    memory: true,
};

var randomColorBalloons = new generativeText(rules7, opts7);
randomColorBalloons.applyToElementById("example7");
            

<div id="example7">Happy Birthday!</div>
            

#example7 span {
    border-radius: 50%;
    padding: 0.2em;
    font-family: 'Bangers';
    font-size: 1.2em;
    border: 2px solid #eeee30;
    width: 1em;
    box-shadow: 2px 2px 4px #606060;
    text-shadow: 2px 2px 4px #606060;
}