Using the Handy renderer

To create Processing sketches using a hand-drawn style, you need firstly to import the Handy library with the line

 
import org.gicentre.handy.*;
 

The hard work of doing the sketchy drawing is done by a HandyRenderer. The renderer should be created once in setup() and then used in your draw() method. It contains methods to draw basic shapes that you are probably familiar with from Processing. These include point(), line(), triangle(), rect(), quad() and ellipse(). Additionally, you can create arbitrary shapes with beginShape(), vertex() and endShape(), just as you would using the normal Processing renderer. For convenience we recommend that you call the Handy renderer h. The sketch below shows a simple example:

A simple sketchy rectangle

import org.gicentre.handy.*;

HandyRenderer h;

void setup()
{
  size(300,200);
  h = new HandyRenderer(this);
}

void draw()
{
  background(235,215,182);
  h.rect(75,50,150,100);
}
 

This produces a rectangle similar to that shown here. The stroke colour, and weight along with its fill colour can be set as normal using Processing's stroke(), strokeWeight() and fill() methods.

If you run the sketch you will see the rectangle 'jitter' as the small random variations in the line position will change on each redraw. This may be desirable, but if not, this can be stopped either by a call to noLoop() (so the rectangle is drawn only once), or by setting the random seed to some fixed value inside the draw loop with a line such as

 
h.setSeed(1234);
 

Styling rendering

You can rely on Processing’s normal fill and stroke styling to control the appearance of you sketchy graphics, such as in the examples below. By default interior shading of shapes is shown as hachures rather than solid colours. The spacing of these lines is, by default, determined by the current stroke weight.

Changing  sketchy fills and strokes

import org.gicentre.handy.*;

HandyRenderer h;

void setup()
{
  size(300,200);
  h = new HandyRenderer(this);
}

void draw()
{
  background(234,215,182);
  fill(206,76,52);
  strokeWeight(2);
  h.rect(30,60,100,80);

  strokeWeight(0.5);
  fill(19,39,28);
  h.ellipse(220,100,100,80);
}
 

You can at any stage, turn the sketchy rendering off (or back on again) with

 
h.setIsHandy(false);  // Turns sketchy rendering off
h.setIsHandy(true);   // Turns sketchy rendering on again
 

For more precise control over appearance the HandyRenderer has a number of methods for controlling styling that are independent of the current stroke and fill settings. These are detailed in the next section.

 

Colour

In all cases, you should specify colours using Processing’s color() method with appropriate parameters (e.g. one value indicates greyscale, a triplet indicates red, green and blue and four values indicate red, green, blue and opacity.

setBackgroundColour() allows you to set the background colour between hachures.

setSecondaryColour() combined with setUseSecondaryColour(true) allows you to add a further tint to the hachures for more subtle colouring effects.

You can set the renderer’s fill and stroke colours independently of Processing's current fill and stroke colours by calling setFillColour() in combination with setOverrideFillColour(true) and by calling setStrokeColour() combined with setOverrideStrokeColour(true).

Changing colour styles

import org.gicentre.handy.*;

HandyRenderer h;

void setup()
{
  size(300,200);
  h = new HandyRenderer(this);
  h.setOverrideFillColour(true);
  h.setOverrideStrokeColour(true);
}

void draw()
{
  background(234,215,182);

  h.setBackgroundColour(color(255));
  h.setFillColour(color(206,76,52));
  h.setStrokeColour(color(0));
  h.rect(50,30,80,50);

  h.setBackgroundColour(color(255,130));
  h.rect(170,30,80,50);

  h.setBackgroundColour(color(0,0));
  h.setStrokeColour(color(206,76,52));
  h.rect(50,120,80,50);

  h.setBackgroundColour(color(206,76,52));
  h.setFillColour(color(19,39,28));
  h.setStrokeColour(color(200,70,48));
  h.rect(170,120,80,50);
}
 

Filling with hachures

The style of the hachures can be controlled with methods to change their thickness (setFillWeight()), their spacing (setFillGap()) and their direction (setHachureAngle()). You can also choose to alternate hachures in a zig-zag pattern with setIsAlternating(true). If you wish the hachure angle to vary slightly between shaded objects, you can add a random angular change with setHachurePerturbationAngle(), supplying the angle in degrees of variation you wish to permit. Finally, the degree of 'sketchiness' of all features can be set with the setRoughness() method that takes values between 0 (very precise) and 10 (very messy).

Changing hachure (fill) styles

import org.gicentre.handy.*;

HandyRenderer h;

void setup()
{
  size(300,200);
  h = new HandyRenderer(this);
  fill(206,76,52);
  h.setHachurePerturbationAngle(15);
}

void draw()
{
  background(234,215,182);
  h.setRoughness(1);

  h.setFillGap(0.5);
  h.setFillWeight(0.1);
  h.rect(50,30,80,50);

  h.setFillGap(3);
  h.setFillWeight(2);
  h.rect(170,30,80,50);

  h.setFillGap(5);
  h.setIsAlternating(true);
  h.rect(50,120,80,50);

  h.setRoughness(3); 
  h.setFillWeight(1);
  h.setIsAlternating(false);
  h.rect(170,120,80,50);
}
 

Preset styles

Finally, to save the effort of setting stroke and fill styles, you may wish to use one or more the preset hand drawn styles available in the handy library. These include styles for creating pencil, marker, and watercolour and ink drawings. They can be created by calling the relevant methods from the HandyPresets class as shown below.

Four preset sketchy styles

import org.gicentre.handy.*;

HandyRenderer h1,h2,h3,h4;

void setup()
{
  size(610,200);
  noLoop();
  h1 = HandyPresets.createPencil(this);
  h2 = HandyPresets.createColouredPencil(this);
  h3 = HandyPresets.createWaterAndInk(this);
  h4 = HandyPresets.createMarker(this);
}

void draw()
{
  background(234,215,182);
  for (int i=0; i<5; i++)
  {
    fill(206+random(-30,30),76+random(-30,30),52+random(-30,30),160);
    h1.rect(random(10,200),random(10,50),80,50);
    h2.rect(random(310,520),random(10,50),80,50);
    h3.rect(random(10,200),random(100,140),80,50);
    h4.rect(random(310,520),random(100,140),80,50);  
  }
}