Created
February 27, 2019 01:21
-
-
Save stenson/4b0ed476877f5b31957d532b10edc148 to your computer and use it in GitHub Desktop.
recreating the very cool typographics 2019 "speakers announced" gif with drawbot
This file contains 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
from furniture.animation import Animation | |
from furniture.vfont import scale_to_axis | |
from grafutils.text.lockup import GlyphLockup # currently unavailable publicly, in-development | |
from drawBot import * | |
colors = [ | |
[1.0, 0.0, 0.48], | |
[1.0, 0.89, 0.15], | |
[0.07, 0.69, 0.94], | |
[0.14, 0.69, 0.64], | |
[0.85, 0.07, 0.15], | |
[0.84, 0.66, 0.1], | |
[1.0, 0.84, 0.71], | |
[0.3, 0.71, 0.07], | |
[0.99, 0.39, 0.25], | |
[1.0, 0.0, 0.48], | |
] | |
colors += list(reversed(colors))[:] | |
# tried to calculate these automatically but loses some of the hand-made vibe of the original | |
wghts = (800, 750, 700, 650, 600, 550, 500, 400, 350, 320, 280, 260) | |
axes1 = (800, 700, 600, 500, 400, 320, 300, 260, 250, 247, 247, 200) | |
axes2 = (800, 700, 600, 500, 400, 320, 280, 230, 210, 200, 200, 200) | |
texts = ["SPEAKERS", "ANNOUNCED"] | |
attrs = dict(font="Obviously Variable", fontSize=280) | |
fs = FormattedString(**attrs) | |
axes = fs.listFontVariations() | |
wdth = axes.get("wdth") | |
wght = axes.get("wght") | |
def draw(frame): | |
li = frame.i//10 | |
lir = frame.i%10 | |
fill(1) | |
rect(*frame.page) | |
fill(*colors[li], 0.9) | |
rect(*frame.page) | |
inset = frame.page.inset(536, 0) | |
def slug(i, offset, align, axes, exiting): | |
stage = li | |
if exiting: | |
stage = 10 - (li - 9) | |
s = texts[i] | |
if align == "left": | |
s = s[:stage+1] | |
mover = stage | |
if align == "right": | |
s = s[::-1][:stage+1][::-1] | |
mover = 0 | |
if stage >= len(s): | |
mover = 1000 # impossible | |
if len(s) > 0: | |
fs = FormattedString(**attrs, align=align) | |
for i, c in enumerate(s): | |
_stage = stage | |
if exiting: | |
if i == mover: | |
fs.fontVariations( | |
wdth=scale_to_axis(wdth, lir/10+0.2), | |
wght=scale_to_axis(wght, lir/10+0.2)) | |
else: | |
fs.fontVariations(wdth=axes[9], wght=wghts[9]) | |
else: | |
if i == mover: _stage += 1 | |
#else: print(axes[_stage], wghts[_stage]) | |
fs.fontVariations(wdth=axes[_stage], wght=wghts[_stage]) | |
fs.append(c) | |
lockup = GlyphLockup(fs, frame.page.inset(-500, 0)) | |
lockup.center(horizontal=False) | |
fill(0) | |
for i, g in enumerate(lockup.glyphs): | |
g.bp.translate(*offset) | |
if i == mover: | |
p = pow((10-lir)/10, 2) | |
if exiting: | |
p = (1 - p)*0.85 | |
if align == "left": | |
g.bp.translate(p*1150) | |
elif align == "right": | |
g.bp.translate(-p*1150) | |
drawPath(g.bp) | |
else: | |
drawPath(g.bp) | |
if frame.i < 100: | |
slug(0, (1020, 140), "left", axes1, False) | |
slug(1, (-1020, -140), "right", axes2, False) | |
else: | |
slug(0, (1020, 140), "left", axes1, True) | |
slug(1, (-1020, -140), "right", axes2, True) | |
animation = Animation(draw, 200, dimensions=(1920, 1080)) | |
animation.storyboard(frames=(45, 50)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment