Skip to content

0.12.0 (Color Parsing)

Release 0.12.0

Release Summary (Color Sequence Parsing, Background Colors, and Tests)

This release features three new effects, Highlight, LaserEtch, and Sweep as well as support for parsing existing color sequences from the input data. Support for background colors has been added throughout the engine. There are many smaller changes such as improved bezier curves, custom easing functions, and various optimizations, some of which will be detailed below.

It's Been A While


It has been nearly 8 months since the last release. That's entirely due to life changes on my end that kept me away from TTE development. I have not been able to work on TTE consistently for about six of those months. Things have settled and I am now able to dedicate time each week to this project (and new projects). Expect more frequent updates from now on.

New Effects (Highlight, LaserEtch, Sweep)


First up, there are three new effects.

Highlight

The Highlight effect runs a specular highlight across the text. To best demonstrate this effect, I will use a solid block of text.

highlight_block_demo

The highlight brightness, width, and direction are all customizable.

LaserEtch

The LaserEtch effect burns the text into the terminal, sending sparks flying. As the sparks fall, they cool and disappear. If the sparks reach the bottom of the canvas before burning out, they will land on the bottom.

laseretch_demo

The etch speed, laser colors, spark colors and all gradients are customizable.

Sweep

The Sweep effect makes two passes over the canvas. On the first pass, the text is revealed, dimmed, and without color. On the second pass, the text is colored.

sweep_demo

The sweep directions and sweep noise symbols are customizable. On the second sweep, the noise takes on colors from the final gradient.

Color Sequence Parsing


TTE can now parse 8/24-bit color sequences from the input data, and associate them with the characters to which they should be applied. This includes both foreground and background sequences.

The following ANSI escape sequence formats are supported:
8-bit Sequences
  • ESC[38:5:⟨n⟩m Select foreground color
  • ESC[48:5:⟨n⟩m Select background color

24-bit Sequences

  • ESC[38;2;⟨r⟩;⟨g⟩;⟨b⟩ m Select RGB foreground color
  • ESC[48;2;⟨r⟩;⟨g⟩;⟨b⟩ m Select RGB background color

Wikipedia - ANSI escape codes


There is a new TerminalConfig command line argument --existing-color-handling that determines how these sequences are used within effects.

There are three options for the --existing-color-handling argument:

dynamic

When set to 'dynamic', each effect will determine how the input sequences are handled.

always

When set to 'always', no other color will be applied to the characters. They will always reflect the colors as provided in the input text. In most cases, this setting will result in an effect that loses much of its design.

ignore

When set to 'ignore', the input colors will be ignored. This is the default.

Color Handling Example

I recommend using a tool such as ASCII Silhouettify to turn your art into ASCII.

In the example below, ASCII Silhouettify was used to process the image into ASCII with color sequences. The ASCII was piped directly into TTE. Each of the color handling options is demonstrated.

astro_planet_balloon

                        ___-mmma___                                               
                    _s"-_"~gggg~""= .<-_                                          
                _r_g@@@@@@@@@@D"r_g@p"q_a                                        
                ,fg@@@@@@@@@D"o"o@@@@@@@P,"_o   ________                           
            /,@@@@@@B>_="g@@@@@@@@P,"o@@_ '(._-..q_ q_a                         
            jJ{@P".="<@@@@@@@@@P"=_g@@"~"g@' [ ].,[@,jW[                         
            /_""~g@@@@@@@@@@P_="g@@P_+_@@@P_@.]F,_gP gPf                          
            /@ @@@@@@@@P"o"_@@@P_="g@@@>_P'_+.~_@"_wP;                            
            ..@,@BP".="_g@@D"->_g@@@>_*'_s",__@P _@"r                              
            ' >"_g@@@B="<>_g@@@B>-"~"o"_ "gB"~_@"o"                                
            ;D=_"s>"o@@@@B>'_->_="~ _g@P _gP"s"@                                  
        _>t"@@@_<4+"~_w>_="_^,_gB" _gD",>_D_,'                                  
        -_u_Fo"gg@B>"o*"_'~_g@P"~_gM",>_d"o@B"F                                   
    __1@1%mmP>"_gy@@@@@@.__~"""s"~8"<@@P"_'/                                    
    0gW@@@@@@W@@@Q$@B@@@B>_s"_m>_g@@P"_g@Ps                                      
    1@@g5@@@@@g@@D>"-="_mD"_g@@D>__g@@@"+                                        
    '<=mmm==>""   "a_4@BP>"__g@@@BP"r"                                          
                        "<==mmy=""                                               
                                ]                                                  
                                ]                                                  
        _~~B>"""->._            ]                                                  
    ,+_^~-"_@@B==4@g_g_         ]                                                  
,/gF^f_@P_g@BBBB@@_4@@,       ]                                                  
__@,/_@[_~g@@@@@@@g_8L0@L   _~~1_                                                 
,/@,//@@@@@@@@@@@@@@@@'gQ@\ jd/|g]h                                                
|@g'/@@@@@@@@@@@@@@@@@@'[@@//'.<>/[                                                
@|.:@/gp\@@@@@@@@@@@@@@@@@ @ L=r_'                                                
!@h,,@'@@"@@@@@@@@@@@@@@@@@.@@']\                                                  
]"==a<)@+"@@@@@@@@@@@@@B2#F@g, " ',                                                
F@@@_`qt\oW@BP@@@@0S$W@@'/AB"f|    \                                               
l4@@@_,!r0@@@@@@@@@@@P,^"g+@WJ                                                     
^'@@P/_<.<-_"""""_+"_"oFg@\s     _                                                
    ">_"=_""""_<"_@"g@@@@`,                                                     
        !!|0@@@@BP"_g@@P"~":aV_                                                    
        '_;@@@Fa[@@P+faB=4@\9p\[                                                   
        @[@@@' [@B___`' `[,"~ ,                                                   
        [@@@'[-mm=>"_''qB>J~"g[                                                   
        [!@@;TR"""~__~~_g@@P'T[                                                   
        |[@@g_"LG@@@@[g""~_-_@[                                                   
        |[@@@8-"@@@@@@F@ "_@@8|                                                   
        {:"_r]  8"==*"~T'*8="-                                                    
                ;/@@@"_ ]|@@+_1                                                    
                [@@@@g| [\@@@@,                                                    
                !`@@@F'  \*"="'                                                    
                ".""_"    """                                                     

Dynamic Color Sequence Handling

The beams effect supports dynamic color handling which results in the standard gradient being replaced with the colors parsed from the input data. The beams, however, keep their color.

beams_astro_dynamic

Always Color Sequence Handling

The characters never deviate from the input colors. This results in the beams taking on the color of the character as they pass over. The dimming effect is not applied.

beams_astro_always

Ignore Color Sequence Handling

The color sequences are parsed and removed from the input. The result is the normal effect behavior.

beams_astro_ignore

Support for dynamic color handling has not been added to all effects. To track the progress of this feature, see this Issue.

Background Colors


TTE now supports specifying background colors throughout the engine. In calls which expect color values, a ColorPair object, providing a foreground and/or background color is used.

There are no effects currently which use background colors.


Ease All The Things

easing is easy

Easing Closure

A new easing function is available that provides a closure around an arbitrary ease.

Example:

import terminaltexteffects as tte

bounce_ease = tte.easing.eased_step_function(easing_func=tte.easing.out_bounce, 
                                             step_size=0.01)
print(bounce_ease())
print(bounce_ease())
print(bounce_ease())
print(bounce_ease())

Output:

(0.0, 0.0)
(0.01, 0.0007562500000000001)
(0.02, 0.0030250000000000003)
(0.03, 0.00680625)

Every call to bounce_ease above, outputs a tuple of (current step, eased value). Once the current step reaches 1, the function will stop increasing the step and the return value will never change.

The wipe effect supports arbitrary easing via this new function. Here is an example of the out_bounce easing function applied to the progression of the wipe.

bounce_wipe

Custom Cubic Bezier Ease

In addition to the function above, a new easing function has been added which allows for the specification of completely custom easing function using bezier control points. An example follows.

Here, I'll use cubic-bezier.com to visually build a curve. The x-axis is time, in our case each call to the ease function will progress one unit across the x-axis. The y-axis is the progression of the function. The bottom is 0, the top is 1.

cubic-bezier.com

I will apply the control points seen in the image above, (0, .81, .98, .22) to the easing function and pass the function to the ease argument when creating a new Path. The target Coord will be the right side of the canvas.

target_coord = tte.Coord(
    self.terminal.canvas.right,
    self.terminal.canvas.center_row,
)
pth = test_char.motion.new_path(ease=tte.easing.make_easing(0, 0.81, 0.98, 0.22), 
                                speed=0.5)
pth.new_waypoint(target_coord)

With the custom easing function applied to the motion of a single character traveling across the canvas, we would expect to see the character move quickly at first, slow down towards the center, and speed up again as it progresses to the right of the canvas.

custom_eased_path

Misc Optimizations and Fixes

This updates includes many fixes and optimizations, details can be found in the full changelog.

Testing

Now that TTE has grown in scale beyond that which I can meaningfully test manually, a full suite of unittests has been added. Pytest is fun, and parameterization has enabled the testing of all effects, with all of their arguments, and a representative sample of the acceptable ranges for those arguments. This was simply impossible manually. All together, there are approximately 30,000 tests run against the codebase, taking about seven minutes.


Plain Old Changelog

0.12.0