Skip to content

Instantly share code, notes, and snippets.

@frankrolf
Created June 3, 2018 23:16
Show Gist options
  • Save frankrolf/ad879e7c8d5ca2ed9f4026c6ea371e57 to your computer and use it in GitHub Desktop.
Save frankrolf/ad879e7c8d5ca2ed9f4026c6ea371e57 to your computer and use it in GitHub Desktop.
DrawBot script to create joyful GIF animations of interpolated glyphs
'''
Type@Cooper West, June 2018
Contribution to Andy Clymer's "Expanding a Type Family" workshop
Script to create joyful GIF animations of interpolated glyphs,
either colorful or black & white.
'''
from fontTools.pens.cocoaPen import CocoaPen
import os
import colorsys
from math import sin, pi
from fontParts.nonelab import RFont, RGlyph
# maybe fontshell?
doc_height = doc_width = 1200
def draw_glyph(glyph):
cpen = CocoaPen(glyph.getParent())
glyph.draw(cpen)
drawPath(cpen.path)
font_light = RFont(os.path.expanduser('~/Desktop/light.ufo'))
font_heavy = RFont(os.path.expanduser('~/Desktop/heavy.ufo'))
glyph_name = 'a'
interpolation_steps = 20
hue_a = randint(0, 255)
hue_b = randint(0, 255)
hue_gamut = hue_b - hue_a
glyph_light = font_light[glyph_name]
glyph_heavy = font_heavy[glyph_name]
interpolation_steps = 20
for frame in range(interpolation_steps):
# calculate time value t
t = frame / interpolation_steps
# calculate an angle in radians based on t, from which we can
# deduce a sine wave
angle = 2 * pi * t
factor = sin(angle)
# interpolate the glyph by the interpolation factor
interpolated_glyph = RGlyph()
interpolated_glyph.interpolate(
0.5 + factor / 2, glyph_light, glyph_heavy)
interpolated_glyph_alt = RGlyph()
# calculate a hue based on the interpolation factor
hue = hue_a + (hue_gamut / 2 * factor)
color = colorsys.hls_to_rgb(hue / 255, 0.5, 1)
# glyph measurements for scaling
bbox_height = interpolated_glyph.bounds[3] - interpolated_glyph.bounds[1]
bbox_top = interpolated_glyph.bounds[3]
overshoot = interpolated_glyph.bounds[1]
# calculate scale factor so the glyph fits optimally into our square
margin = 20
scale_factor = (doc_height - (2 * margin)) / bbox_height
# draw the pages
newPage(doc_height, doc_width)
frameDuration(1 / interpolation_steps * 2)
# background fill
fill(0)
rect(0, 0, width(), height())
# letter fill
fill(*color) # colorful
# fill(1) # white
# calculate space around the glyph (so we can center it)
padding = (width() - 2 * margin - interpolated_glyph.width) / 2
save()
# scale and translate the glyph, and finally dtaw it
scale(scale_factor, scale_factor, center=(width()/2, 0))
translate(margin, margin - overshoot / 2)
translate(padding, 0)
draw_glyph(interpolated_glyph)
restore()
# save as GIF
saveImage('~/Desktop/interpolation.gif')
# save as movie
# saveImage('~/Desktop/interpolation.mov')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment