Clipping regions in generativepy


Martin McBride, 2020-10-04
Tags generativepy tutorial path
Categories generativepy generativepy tutorial

This tutorial covers the basics of using clipping regions in generativepy.

A clipping region defines the area of the page that you can draw on. If you draw a shape that is inside the clipping region, it will be visible, if you draw a shape that is outside the clipping region it will not be visible. If a shape is partly inside the clipping region, it will be clipped so that only the part that is inside the region is visible. This can create interesting effects, especially with a complex clipping region.

Clipping example code

Here is a sample Python program that creates two different clipping regions. The code is explained later in this article:

from generativepy.drawing import make_image, setup
from generativepy.color import Color
from generativepy.geometry import Circle, Square, Text
import math

def draw(ctx, width, height, frame_no, frame_count):
    setup(ctx, width, height, width=5, background=Color(0.8))

    # Create a circular clip region and draw some squares in it
    ctx.save()
    Circle(ctx).of_center_radius((1.9, 1.9), 1).clip()
    Square(ctx).of_corner_size((1, 1), .8).fill(Color('red'))
    Square(ctx).of_corner_size((1, 2), .8).fill(Color('green'))
    Square(ctx).of_corner_size((2, 1), .8).fill(Color('blue'))
    Square(ctx).of_corner_size((2, 2), .8).fill(Color('black'))
    ctx.restore()

    # Create a text clip region and fill it with circles
    ctx.save()
    Text(ctx).of("ABC", (1.5, 3.5))\
             .font("Times")\
             .size(1.5)\
             .align_left()\
             .align_top()\
             .clip()
    circles = [(2, 3.8, 'orange'), (2, 4.5, 'cyan'), (3, 3.8, 'green'),
               (3, 4.5, 'purple'), (4, 3.8, 'yellow'), (4, 4.5, 'blue')]
    for x, y, color in circles:
        Circle(ctx).of_center_radius((x, y), 0.7).fill(Color(color))
    ctx.restore()


make_image("clip-method.png", draw, 500, 500)

Here is the resulting image:

Circular clipping path

The first part of the code creates a circular clip region, and draws some squares inside it:

    ctx.save()
    Circle(ctx).of_center_radius((1.9, 1.9), 1).clip()
    Square(ctx).of_corner_size((1, 1), .8).fill(Color('red'))
    Square(ctx).of_corner_size((1, 2), .8).fill(Color('green'))
    Square(ctx).of_corner_size((2, 1), .8).fill(Color('blue'))
    Square(ctx).of_corner_size((2, 2), .8).fill(Color('black'))
    ctx.restore()

In this case, we have created a Circle in the usual way, but instead of filling or stroking the shape, we call clip. This sets the circle as the clip-path. Only the parts of the image inside the circle can be marked.

We then draw 4 squares that are partly inside and partly outside the clip region. As you can see from the final image above each square is clipped to the shape of the circle.

Notice that we use ctx.save at the start of the code block. This stores the current state of the drawing context. This state includes the clip-path, which initially includes the entire image.

After drawing the squares, we call ctx.restore, which restores the original drawing state. This has the effect of removing the clip-path, so the whole page can be drawn on again. See useful context methods for more information about this.

Text clipping path

The second part of the code creates a complex clip region that takes the shape of the text string "ABC" drawn in a large font. The code then draw some overlapping coloured circles. These are clipped to the text shape:

    ctx.save()
    Text(ctx).of("ABC", (1.5, 3.5))\
             .font("Times")\
             .size(1.5)\
             .align_left()\
             .align_top()\
             .clip()
    circles = [(2, 3.8, 'orange'), (2, 4.5, 'cyan'), (3, 3.8, 'green'),
               (3, 4.5, 'purple'), (4, 3.8, 'yellow'), (4, 4.5, 'blue')]
    for x, y, color in circles:
        Circle(ctx).of_center_radius((x, y), 0.7).fill(Color(color))
    ctx.restore()
If you found this article useful, you might be interested in the book Computer Graphics in Python or other books by the same author.

Prev

Popular tags

2d arrays abstract data type alignment and animation arc array arrays behavioural pattern bezier curve built-in function callable object chain circle classes close closure cmyk colour combinations comparison operator comprehension context context manager conversion count creational pattern data types design pattern device space dictionary drawing duck typing efficiency ellipse else encryption enumerate fill filter font font style for loop function function composition function plot functools game development generativepy tutorial generator geometry gif gradient greyscale higher order function hsl html image image processing imagesurface immutable object index inner function input installing iter iterable iterator itertools l system lambda function len line linear gradient linspace list list comprehension logical operator lru_cache magic method mandelbrot mandelbrot set map monad mutability named parameter numeric python numpy object open operator optional parameter or partial application path pattern permutations polygon positional parameter print pure function python standard library radial gradient range recipes rectangle recursion reduce repeat rgb rotation scaling sector segment sequence setup shape singleton slice slicing sound spirograph sprite square str stream string stroke structural pattern subpath symmetric encryption template text text metrics tinkerbell fractal transform translation transparency triangle tuple turtle unpacking user space vectorisation webserver website while loop zip