Created
June 3, 2018 23:16
-
-
Save frankrolf/ad879e7c8d5ca2ed9f4026c6ea371e57 to your computer and use it in GitHub Desktop.
DrawBot script to create joyful GIF animations of interpolated glyphs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
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