@frederik Thank you!
I fiddled around a bit today and managed to get a result pretty close with the code below.
The solution was to chop everything off <= 0.
Playing around with easing functions for the framePhase resulted in some interesting visuals as well.
I’ll admit it’s probably not the pretties code but it gets the job done. If anyone has some other ideas or upgrades for the code block below I am always keen to learn something new. Especially as I am planning to play around a bit more with wave based animations.
CANVAS = 1080
numFrames = 35
amp = CANVAS
tailLength = 1.1
txt = "CODING"
pt = 180
def setFontStyle(color = 0):
fontSize(pt)
fill(color)
stroke(0)
lineJoin("round")
strokeWidth(5)
def drawShadow(_txt, x, y):
with savedState():
setFontStyle(.8)
stroke(None)
translate(25, -15)
text(char, (x, y))
def drawChar(char, x, y, color):
with savedState():
setFontStyle(color)
text(char, (x, y))
def f(firstPhase, secondPhase, thirdPhase):
return(sin(.5 * pi * secondPhase - thirdPhase - firstPhase - pi * 1.4))
fontSize(pt)
amp -= fontCapHeight()
capHeight = fontCapHeight()
for frame in range(numFrames):
fPhase = (2 * pi) * frame / numFrames
newPage(CANVAS, CANVAS)
fill(1)
rect(0, 0, CANVAS, CANVAS)
scale(.9, center = (width()/2, height()/2))
for i, char in enumerate(txt):
txtPhase = i / len(txt)
for j in range(4):
colPhase = (i + j * tailLength) / (4 + len(txt))
x = f(fPhase, txtPhase, colPhase)
if x <= 0:
x = 0
y = 90 + capHeight * len(txt) - 1.2 * capHeight * i
drawShadow(char, x * amp, y)
for i, char in enumerate(txt):
txtPhase = i / len(txt)
for j in range(4):
colPhase = (i + j * tailLength) / (4 + len(txt))
x = f(fPhase, txtPhase, colPhase)
if x <= 0:
x = 0
y = 90 + capHeight * len(txt) - 1.2 * capHeight * i
drawChar(char, x * amp, y, (j / 3))
saveImage(f"~/Desktop/TypeTrail.gif")
Will result in something like this: