Type Wave Animation



  • Hey πŸ™‚
    I found a GIF online (haven’t found better credits for it) that I am currently trying to recreate in DrawBot.

    For now I managed to create a wave effect from left to right with the code below.
    But I am having a hard time to utilize wave functions to full extend to achieve the result that I want to recreate.

    Especially offsetting the wave so it seems to be running through the text just once. I feel like this is somehow related to the topic Delay Animation but I am not able to adapt it.
    It feels like I am still missing the fundamental idea of using wave functions for animations like this. If any of you has some resource, articles or suggestion I appreciate it a lot. πŸ™Œ

    numFrames = 35
    start, marginTop = 450, 90
    travel = 400
    txt = "CODING"
    
    
    def drawShadow(_txt, x, yy):
        with savedState():
            translate(25, -15)
            fill(.8)
            text(_txt, (x, yy + fCapHeight * len(txt) - i * fCapHeight*1.20))
    
    def drawChar(_txt, x, yy):
        with savedState():
            text(_txt, (x, yy + fCapHeight * len(txt) - i * fCapHeight*1.20))
                
        
    for frame in range(numFrames):  
        fPhase = frame / numFrames
        newPage(1080, 1080)
        fill(1, 1, 1)
        rect(0, 0, width(), height())
        
        fontSize(180)
    
        fCapHeight = fontCapHeight()
    
        lineJoin("round")
        
        for i, char in enumerate(txt):
            for j in range(4):
                _travel = travel * sin(2 * pi * fPhase + (i + j * .8) / 4 + len(txt))
                drawShadow(char, start + _travel, marginTop)
        
        for i, char in enumerate(txt):
            cPhase = i / len(txt)
            stroke(0, 0, 0)
            strokeWidth(5)
            for j in range(4):
                fill(j / 3)
                _travel = travel * sin(2 * pi * fPhase + (i + j * .8) / 4 + len(txt))
                drawChar(char, start + _travel, marginTop)
                
    saveImage("~/Desktop/waveAnimation.gif")
    

    Results in a GIF like this.

    waveAnimation.gif

    And this is a more advanced version that I managed to create.
    TypeWave.gif


  • admin

    looks already cool!

    The big difference between yours and the example you refer to is that the letters wait until all the following shaded letters arrive to the left and the right.



  • @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:
    TypeTrail.gif


Log in to reply