Text Randomiser

Here’s a script I wrote for Illustrator to give the option to gently randomise the letters inside a text box to give it a slightly more organic aesthetic.

I wrote about it on my newsletter, which you can read here.

If you are going to use this, remember to back your work up first and maybe give it a try on a couple of test documents before getting deep into a prestige project.

To use this script, save it as a .js file, and then put that in your  /illustrator/Presets/Scripts folder. It should then appear under file-scripts. Select a text box first, then run it and play around with it to get the desired effect.

				
					#target illustrator

function main() {
    if (app.documents.length == 0) {
        alert('Open a document and select a text frame to proceed');
        return;
    }

    var doc = app.activeDocument;
    var selection = doc.selection;
    if (selection.length == 0 || !(selection[0] instanceof TextFrame)) {
        alert('Please select one or more text frames and try again');
        return;
    }

    // Create a dialog box for input
    var dialog = new Window('dialog', 'Randomize Text');

    // Add sliders for rotation, displacement, size, spacing and colour.
    var angleSlider = addSlider(dialog, 'Max Rotation Angle:', 0, 3, 3);
    var displacementSlider = addSlider(dialog, 'Max Displacement:', 0, 2, 0.1);
    var sizeSlider = addSlider(dialog, 'Max Size Variation:', 0, 3, 0.2);
    var spaceSlider = addSlider(dialog, 'Max Spacing Variation:', 0, 2, 0.1);
    var colorSlider = addSlider(dialog, 'Max Color Variation:', 0, 1, 0);

    // Add 'OK' and 'Cancel' buttons
    var buttonGroup = dialog.add('group');
    buttonGroup.alignment = 'right';
    buttonGroup.add('button', undefined, 'OK', { name: 'ok' });
    buttonGroup.add('button', undefined, 'Cancel', { name: 'cancel' });

    if (dialog.show() === 1) {  // If user clicked 'OK'
        var maxAngle = angleSlider.value;
        var maxDisplacement = displacementSlider.value;
        var maxSizeVariation = sizeSlider.value;
        var maxSpaceVariation = spaceSlider.value;
        var maxColorVariation = colorSlider.value;

        // Apply effect to each selected text frame
        for (var k = 0; k < selection.length; k++) {
            if (!(selection[k] instanceof TextFrame)) {
                continue;  // Skip if the selected item is not a text frame
            }

            var textFrame = selection[k]; // Get the selected text frame

            // Duplicate and hide the original text frame
            var originalTextFrame = textFrame;
            originalTextFrame.visible = false;
            textFrame = originalTextFrame.duplicate();
            textFrame.selected = true;

            // Convert text to outlines
            textFrame = textFrame.createOutline(); // textFrame is now a group item

            for (var i = 0; i < textFrame.pageItems.length; i++) {
                var character = textFrame.pageItems[i]; // current character
                var angle = Math.random() * maxAngle - maxAngle / 2; // random angle between -maxAngle/2 and maxAngle/2
                var dx = (Math.random() - 0.5) * maxDisplacement; // random displacement along x
                var dy = (Math.random() - 0.5) * maxDisplacement; // random displacement along y
                var size = 1 + ((Math.random() - 0.5) * maxSizeVariation / 100); // size variation
                var space = (Math.random() - 0.5) * maxSpaceVariation; // spacing variation
                var grayVariation = (1 - maxColorVariation) * 100 + Math.random() * maxColorVariation * 100; // gray color variation

                character.rotate(angle);
                character.resize(size * 100, size * 100, true, true, true, true, size * 100, Transformation.DOCUMENTORIGIN);
                character.translate(dx + space, dy);

                var grayColor = new GrayColor();
                grayColor.gray = grayVariation; // Now properly scaled from 0 to 100

                // Apply gray color to all pathItems of the character
                for (var j = 0; j < character.pathItems.length; j++) {
                    var path = character.pathItems[j];
                    path.fillColor = grayColor;
                }
            }
        }
    }
}

function addSlider(parent, text, min, max, value) {
    var group = parent.add('group');
    group.add('statictext', undefined, text);
    var slider = group.add('slider', undefined, value, min, max);
    slider.size = [200, 20];  // Size of the slider
    var edittext = group.add('edittext', undefined, value);
    edittext.characters = 5;  // Width of the edittext box
    edittext.justify = 'right';

    // Update the slider when the user types a value
    edittext.onChanging = function () {
        slider.value = parseFloat(edittext.text);
    };

    // Update the value when the user moves the slider
    slider.onChanging = function () {
        edittext.text = Number(slider.value).toFixed(2); // Here we've changed to allow decimal values
    };

    return slider;
}

main();