Documentation
¶
Overview ¶
Package tuiffects animates terminal text.
It is a Go port of ttfx, which is itself a port of TerminalTextEffects by ChrisBuilds. Every effect here, and the architecture of the engine that runs them, are that project's design; this package originates none of the art. See NOTICE for the full chain and LICENSE for the three copyrights it carries.
Index ¶
- Variables
- func Choice[T any](g *Rng, items []T) *T
- func FindLengthOfBezierCurve(start Coord, control []Coord, end Coord) float64
- func FindLengthOfLine(a, b Coord, doubleRowDiff bool) float64
- func FindNormalizedDistanceFromCenter(bottom, top, left, right int, other Coord) (float64, bool)
- func LinkCharacters(a, b *Character)
- func Names() []string
- func Register(d Descriptor)
- func Run(effect Effect, e *Engine, maxFrames int) ([]string, error)
- func Shuffle[T any](g *Rng, items []T)
- type Action
- func ActivatePath(id string) Action
- func ActivateScene(id string) Action
- func Callback(fn func(e *Engine, ch *Character)) Action
- func DeactivatePath(id string) Action
- func DeactivateScene(id string) Action
- func ResetAppearance() Action
- func SetCoordinate(coord Coord) Action
- func SetLayer(layer int) Action
- type Anchor
- type Animation
- func (a *Animation) ActiveSceneIsComplete() bool
- func (a *Animation) ClearScenes()
- func (a *Animation) CurrentVisual() *CharacterVisual
- func (a *Animation) NewScene(id string, opts SceneOptions) *Scene
- func (a *Animation) Scene(id string) *Scene
- func (a *Animation) SetAppearance(symbol string, colors ColorPair, usesInputColors bool)
- type BinaryPath
- type BinaryPathConfig
- type Blackhole
- type BlackholeConfig
- type BouncyBalls
- type BouncyBallsConfig
- type BreadthFirst
- type Bubbles
- type BubblesConfig
- type Burn
- type BurnConfig
- type Caller
- type Canvas
- type Character
- type CharacterFilter
- type CharacterGroup
- type CharacterSort
- type CharacterVisual
- type Clock
- type Color
- type ColorPair
- type Coord
- func C(column, row int) Coord
- func ExtrapolateAlongRay(origin, target Coord, offsetFromTarget float64) Coord
- func FindCoordOnBezierCurve(start Coord, control []Coord, end Coord, t float64) Coord
- func FindCoordOnLine(start, end Coord, t float64) Coord
- func FindCoordsInCircle(center Coord, diameter int) []Coord
- func FindCoordsInRect(origin Coord, distance int) []Coord
- func FindCoordsOnCircle(origin Coord, radius, coordsLimit int, unique bool) []Coord
- func FindCoordsOnRect(origin Coord, halfWidth, halfHeight int) []Coord
- type CoordColorMap
- type Crumble
- type CrumbleConfig
- type Decrypt
- type DecryptConfig
- type Descriptor
- type Easing
- type Effect
- type Engine
- func (e *Engine) Activate(ch *Character)
- func (e *Engine) ActivatePath(ch *Character, pathID string)
- func (e *Engine) ActivateScene(ch *Character, sceneID string)
- func (e *Engine) ActiveCharacters() []*Character
- func (e *Engine) ActiveCount() int
- func (e *Engine) ChainPaths(ch *Character, pathIDs []string, loop bool)
- func (e *Engine) ClearActive()
- func (e *Engine) Deactivate(ch *Character)
- func (e *Engine) DeactivateScene(ch *Character, sceneID string)
- func (e *Engine) Frame() string
- func (e *Engine) FrameRows() [][]*CharacterVisual
- func (e *Engine) MotionMove(ch *Character)
- func (e *Engine) StepAnimation(ch *Character)
- func (e *Engine) Tick(ch *Character)
- func (e *Engine) Update()
- type ErrorCorrect
- type ErrorCorrectConfig
- type EtchPattern
- type Event
- type ExistingColorHandling
- type Expand
- type ExpandConfig
- type ExpandDirection
- type Factory
- type Fireworks
- type FireworksConfig
- type Frame
- type Gradient
- type GradientDirection
- type Highlight
- type HighlightConfig
- type InputCell
- type LaserEtch
- type LaserEtchConfig
- type Matrix
- type MatrixConfig
- type Middleout
- type MiddleoutConfig
- type Motion
- type OrbittingVolley
- type OrbittingVolleyConfig
- type Overflow
- type OverflowConfig
- type ParticlePool
- func (p *ParticlePool) Acquire(e *Engine, symbol string, reset ParticleReset) *Character
- func (p *ParticlePool) AvailableCount() int
- func (p *ParticlePool) Emit(e *Engine, origin Coord, symbol string, visible bool, reset ParticleReset, ...) *Character
- func (p *ParticlePool) Extend(particles ...*Character)
- func (p *ParticlePool) Len() int
- func (p *ParticlePool) Preallocate(e *Engine, count int) error
- func (p *ParticlePool) Reclaim(e *Engine, ch *Character, hide, deactivate bool)
- func (p *ParticlePool) ReclaimOnEvent(ch *Character, event Event, from Caller, hide, deactivate bool)
- type ParticleReset
- type Path
- type PathOptions
- type PopCondition
- type Pour
- type PourConfig
- type PourDirection
- type PrimsSimple
- type PrimsWeighted
- type Print
- type PrintConfig
- type Rain
- type RainConfig
- type RandomSequence
- type RandomSequenceConfig
- type RecursiveBacktracker
- type Rings
- type RingsConfig
- type Rng
- type Scattered
- type ScatteredConfig
- type Scene
- type SceneOptions
- type Segment
- type Slice
- type SliceConfig
- type SliceDirection
- type Slide
- type SlideConfig
- type SlideGrouping
- type Smoke
- type SmokeConfig
- type Spotlights
- type SpotlightsConfig
- type Spray
- type SprayConfig
- type SprayPosition
- type Swarm
- type SwarmConfig
- type Sweep
- type SweepConfig
- type SyncMetric
- type SynthGrid
- type SynthGridConfig
- type Terminal
- func (t *Terminal) AddCharacter(symbol string, coord Coord) *Character
- func (t *Terminal) CharacterAtInputCoord(coord Coord) *Character
- func (t *Terminal) CollectCharacters(filter CharacterFilter) []*Character
- func (t *Terminal) Frame() string
- func (t *Terminal) FrameRows() [][]*CharacterVisual
- func (t *Terminal) GetCharacters(rng *Rng, filter CharacterFilter, order CharacterSort) []*Character
- func (t *Terminal) GetCharactersGrouped(filter CharacterFilter, grouping CharacterGroup) [][]*Character
- func (t *Terminal) Neighbors(ch *Character) []*Character
- func (t *Terminal) SetCharacterVisibility(ch *Character, visible bool)
- type TerminalConfig
- type Thunderstorm
- type ThunderstormConfig
- type TuffBaby
- type TuffBabyConfig
- type Unstable
- type UnstableConfig
- type VhsTape
- type VhsTapeConfig
- type VisualParams
- type Waves
- type WavesConfig
- type Waypoint
- type WeightedLink
- type Wipe
- type WipeConfig
Constants ¶
This section is empty.
Variables ¶
var DynamicNeutralGrey = MustParseColor("808080")
DynamicNeutralGrey stands in for a character that arrived with no foreground of its own, in the effects that need one to work with under DynamicExistingColors. A captured screen is mostly cells with no explicit foreground, and an effect whose whole subject is a colour change has nothing to change on them: the band passes over and nothing happens.
It is a deviation from ttfx, which animates piped text where every character is given a gradient colour and this case never arises. Every use of it is scoped to DynamicExistingColors, so the default behaviour stays upstream's.
var ErrNoParticleSymbols = errors.New("tuiffects: a particle pool needs at least one symbol")
ErrNoParticleSymbols is returned when a pool is built with nothing to draw.
var ErrNoStartingCharacter = errors.New("tuiffects: no character at the spanning tree's starting coordinate")
ErrNoStartingCharacter is returned when a generator picks a random starting coordinate and finds no character on it. It nearly always means the terminal was built without fill characters.
var ErrParticleCountAboveMax = errors.New("tuiffects: cannot preallocate more particles than the pool's maximum")
ErrParticleCountAboveMax is returned when Preallocate is asked for more particles than MaxSize allows.
Functions ¶
func Choice ¶
Choice picks one element. It returns nil for an empty slice, so callers that can be handed an empty option list must check.
func FindLengthOfBezierCurve ¶
FindLengthOfBezierCurve estimates arc length from a 10-sample polyline.
The walk stops at t=0.9 and never adds the last tenth of the curve, so every length comes out short. That is upstream behaviour. It is kept because path speed divides by this number, and correcting it would quietly make every curved path in every effect finish sooner than its author tuned it to.
func FindLengthOfLine ¶
FindLengthOfLine returns the distance between two coords. Terminal cells are about twice as tall as they are wide, so callers that want visually even motion pass doubleRowDiff.
func FindNormalizedDistanceFromCenter ¶
FindNormalizedDistanceFromCenter reports how far a coord sits from the centre of a rectangle, from 0 at the centre to 1 at a corner. It returns false when the coord is outside the rectangle.
func LinkCharacters ¶ added in v0.3.0
func LinkCharacters(a, b *Character)
LinkCharacters joins two characters in both directions.
Each side's Links stays sorted by character id, and linking a pair twice does nothing the second time. Upstream keeps a Python set here; the sort is what makes traversals of it repeatable.
Upstream and ttfx both take the engine as an argument because their characters live in an arena. Here a character is a pointer, so it does not.
func Register ¶
func Register(d Descriptor)
Register adds an effect to the registry. It is meant to be called from an init function, and it panics on a duplicate name because that is a programming mistake rather than a runtime condition.
Types ¶
type Action ¶
type Action struct {
// contains filtered or unexported fields
}
Action is what happens when an event fires.
func ActivatePath ¶
ActivatePath starts a path when the event fires.
func ActivateScene ¶
ActivateScene starts a scene when the event fires.
func Callback ¶
Callback runs effect code. Go closures let the effect keep its own state directly, so this port has no callback id table.
func DeactivatePath ¶
DeactivatePath stops a path. An empty id stops whatever is running.
func DeactivateScene ¶
DeactivateScene stops a scene. An empty id stops whatever is running.
func ResetAppearance ¶
func ResetAppearance() Action
ResetAppearance puts the character back to its input symbol and colours.
type Anchor ¶
type Anchor int
Anchor is one of the nine compass points a block of text can be pinned to inside the canvas.
type Animation ¶
type Animation struct {
ExistingColorHandling ExistingColorHandling
InputColors ColorPair
InputBold bool
// contains filtered or unexported fields
}
Animation is one character's animation state: its scenes, which one is active, and the visual it currently shows.
func (*Animation) ActiveSceneIsComplete ¶
ActiveSceneIsComplete reports whether the active scene has run out of frames. A looping scene always reads as complete, which is upstream's behaviour and the reason a loop-only character counts as inactive.
func (*Animation) ClearScenes ¶ added in v0.3.0
func (a *Animation) ClearScenes()
ClearScenes removes every scene from the character and stops whatever was running. As with Motion.ClearPaths, the active reference goes too.
func (*Animation) CurrentVisual ¶
func (a *Animation) CurrentVisual() *CharacterVisual
CurrentVisual is what the renderer draws for this character right now.
func (*Animation) NewScene ¶
func (a *Animation) NewScene(id string, opts SceneOptions) *Scene
NewScene registers a scene. An empty id gets an auto-allocated one, which is returned. A duplicate id replaces the old scene, as it does upstream.
type BinaryPath ¶ added in v0.4.0
type BinaryPath struct {
// contains filtered or unexported fields
}
BinaryPath breaks every character into the binary digits of its code point, sends those digits on a right-angled path around the canvas, and collapses them back into the character when they arrive. A diagonal wipe then brightens the rebuilt text.
This effect assembles the screen rather than passing over it, so every character stays hidden until its own digits have arrived. That holds under every colour policy, including DynamicExistingColors: showing the picture up front would leave the digits nothing to rebuild.
func NewBinaryPath ¶ added in v0.4.0
func NewBinaryPath(config BinaryPathConfig) *BinaryPath
NewBinaryPath builds the effect.
func (*BinaryPath) Advance ¶ added in v0.4.0
func (b *BinaryPath) Advance(e *Engine) bool
Advance releases another digit from each travelling group, collapses the groups that have arrived, and runs one frame. It reports whether the effect is still going.
func (*BinaryPath) Build ¶ added in v0.4.0
func (b *BinaryPath) Build(e *Engine) error
Build resolves every character's final colour, makes the digits that carry it and the path each digit follows, and gives the character the two scenes it wears once the digits arrive.
type BinaryPathConfig ¶ added in v0.4.0
type BinaryPathConfig struct {
// FinalGradientStops colour the text once it has been rebuilt. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
// BinaryColors are the colours the travelling digits wear. Each digit
// picks one at random.
BinaryColors []Color
// MovementSpeed is how fast a digit travels along its path.
MovementSpeed float64
// ActiveBinaryGroups is how many groups of digits may travel at once, as
// a fraction of the total number of groups. Lower it to do less work per
// frame.
ActiveBinaryGroups float64
}
BinaryPathConfig tunes the binarypath effect.
func DefaultBinaryPathConfig ¶ added in v0.4.0
func DefaultBinaryPathConfig() BinaryPathConfig
DefaultBinaryPathConfig is upstream's default binarypath.
type Blackhole ¶ added in v0.4.0
type Blackhole struct {
// contains filtered or unexported fields
}
Blackhole turns the text into a starfield, forms a rotating ring of stars, pulls every other character into the middle of it, collapses the ring onto the same point, and then explodes the point and lets the characters drift home.
This effect assembles the picture rather than passing over it. The screen it was handed is torn apart in the first frame and only exists again at the end, so there is no DynamicExistingColors deviation for visibility here: upstream already shows every character from frame one, because at that point every character is a star somewhere in the starfield rather than a piece of the picture. Revealing the picture in place up front would show the thing the effect is about to destroy.
func NewBlackhole ¶ added in v0.4.0
func NewBlackhole(config BlackholeConfig) *Blackhole
NewBlackhole builds the effect.
func (*Blackhole) Advance ¶ added in v0.4.0
Advance moves the effect on by one frame and reports whether it is still going.
func (*Blackhole) Build ¶ added in v0.4.0
Build measures the ring, works out where every character settles, and lays out the starfield.
func (*Blackhole) Err ¶ added in v0.4.0
Err reports a failure raised after Build returned. The collapse and the explosion are built while the effect runs, as they are upstream, so their errors cannot be handed back through Build. Advance stops the effect when one happens and leaves it here.
Nothing in either stage can fail with the arguments they are given, so this stays nil in practice. It exists so a failure is reported rather than swallowed.
type BlackholeConfig ¶ added in v0.4.0
type BlackholeConfig struct {
// BlackholeColor is the colour of the stars that make up the ring.
BlackholeColor Color
// StarColors colour the singularity while it is unstable, in the moment
// between the ring collapsing and the explosion. They do not colour the
// explosion itself; see explodeSingularity.
StarColors []Color
// FinalGradientStops colour the text once it is back in place. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
BlackholeConfig tunes the blackhole effect.
func DefaultBlackholeConfig ¶ added in v0.4.0
func DefaultBlackholeConfig() BlackholeConfig
DefaultBlackholeConfig is upstream's default blackhole.
type BouncyBalls ¶ added in v0.4.0
type BouncyBalls struct {
// contains filtered or unexported fields
}
BouncyBalls drops every character in as a ball from somewhere above the canvas, bounces it where the character belongs, and fades the ball into the character once it has come to rest.
It assembles the screen rather than passing over it, so a character stays hidden until its ball is dropped. That holds under every colour policy, including DynamicExistingColors: a character shown before its ball landed would be the picture arriving without the animation that puts it there.
func NewBouncyBalls ¶ added in v0.4.0
func NewBouncyBalls(config BouncyBallsConfig) *BouncyBalls
NewBouncyBalls builds the effect.
func (*BouncyBalls) Advance ¶ added in v0.4.0
func (b *BouncyBalls) Advance(e *Engine) bool
Advance runs one frame and reports whether the effect is still going.
func (*BouncyBalls) Build ¶ added in v0.4.0
func (b *BouncyBalls) Build(e *Engine) error
Build gives every character a ball, a fall path, and a landing fade.
type BouncyBallsConfig ¶ added in v0.4.0
type BouncyBallsConfig struct {
// BallColors are picked at random, one per ball.
BallColors []Color
// BallSymbols are the glyphs a ball can wear on the way down.
BallSymbols []string
// BallDelay is how many frames pass between one group of balls being
// dropped and the next. Raise it to drop fewer balls at once.
BallDelay int
// MovementSpeed is how fast a ball falls.
MovementSpeed float64
// MovementEasing shapes the fall. The default bounces on landing, which
// is what the effect is named for.
MovementEasing Easing
// FinalGradientStops colour the text once a ball has landed. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
BouncyBallsConfig tunes the bouncyballs effect.
func DefaultBouncyBallsConfig ¶ added in v0.4.0
func DefaultBouncyBallsConfig() BouncyBallsConfig
DefaultBouncyBallsConfig is upstream's default bouncyballs.
type BreadthFirst ¶ added in v0.3.0
type BreadthFirst struct {
// StartingChar is where the sweep began.
StartingChar *Character
// ExploredLastStep are the characters this Step reached. This is the
// layer, and it is what an effect animates.
ExploredLastStep []*Character
// CharExploreOrder is every character reached so far, in order. It does
// not include the starting character.
CharExploreOrder []*Character
// Complete says the sweep ran out of frontier.
Complete bool
// contains filtered or unexported fields
}
BreadthFirst walks a tree that one of the generators above has already built, one whole layer per Step. It builds nothing itself and draws no random numbers, so it is what an effect uses to sweep outwards from a point along links that are already there.
func NewBreadthFirst ¶ added in v0.3.0
func NewBreadthFirst(e *Engine, startingChar *Character, limitToTextBoundary bool) (*BreadthFirst, error)
NewBreadthFirst starts a sweep. A nil startingChar picks a random coordinate. The links it follows must already exist: run one of the tree generators to completion first.
func (*BreadthFirst) Step ¶ added in v0.3.0
func (b *BreadthFirst) Step()
Step drains the whole frontier and makes everything it reached the next one. One Step is one layer, however wide that layer is.
type Bubbles ¶ added in v0.4.0
type Bubbles struct {
// contains filtered or unexported fields
}
Bubbles gathers the input into groups of five to twenty characters, hangs each group on the rim of a bubble above the canvas, and drifts the bubbles down one at a time. A bubble bursts when it reaches its row, throws its characters outwards, and each one then flies to where it belongs and ramps from the burst colour into its final colour.
It assembles the screen rather than passing over it. A character is hidden until the bubble carrying it is released, and that holds under every colour policy including DynamicExistingColors: the characters are the bubbles, so showing the finished picture from the first frame would deliver the screen before a single bubble had been let go.
func NewBubbles ¶ added in v0.4.0
func NewBubbles(config BubblesConfig) *Bubbles
NewBubbles builds the effect.
type BubblesConfig ¶ added in v0.4.0
type BubblesConfig struct {
// Rainbow makes each bubble cycle a rainbow instead of wearing one
// colour. BubbleColors is ignored when it is set.
Rainbow bool
// BubbleColors are picked at random, one per bubble.
BubbleColors []Color
// PopColor is the colour of the burst, and the colour every character
// ramps away from as it settles.
PopColor Color
// BubbleSpeed is how fast a bubble drifts down the canvas.
BubbleSpeed float64
// BubbleDelay is how many frames pass between one bubble being released
// and the next.
BubbleDelay int
// PopCondition decides when a bubble bursts.
PopCondition PopCondition
// MovementEasing is upstream's flag of the same name. Neither ttfx nor
// the Python it came from reads it: the burst uses out_expo and the drop
// into place uses in_out_expo, both fixed. It is kept so the config still
// matches upstream's command line, and setting it does nothing.
MovementEasing Easing
// FinalGradientStops colour the text once it has settled. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
BubblesConfig tunes the bubbles effect.
func DefaultBubblesConfig ¶ added in v0.4.0
func DefaultBubblesConfig() BubblesConfig
DefaultBubblesConfig is upstream's default bubbles.
type Burn ¶ added in v0.4.0
type Burn struct {
// contains filtered or unexported fields
}
Burn sets the text alight. A spanning tree grows outwards from a random cell and the fire follows it, two to four characters a frame. A character that has finished burning cools into its final colour and may give off a smoke particle that drifts up off the top of the canvas.
This effect passes over the screen rather than assembling it. Every character is visible and wearing StartingColor from the first frame, in every colour mode, because burn's subject is paper that is already there. So there is no reveal to defer and no waves-style pre-show to add under DynamicExistingColors: the deviation that mode needs here is about backgrounds, not about visibility. See Build.
func (*Burn) Advance ¶ added in v0.4.0
Advance lights the next two to four characters the tree reached and runs one frame. The effect is over once the tree's order has run out and the last character and the last of the smoke have finished.
func (*Burn) Build ¶ added in v0.4.0
Build lights the tree, stocks the smoke pool, and gives every character the two scenes it needs: the fire that crosses it and the cooling that follows.
Deviation, scoped to DynamicExistingColors: a character's background is carried through both scenes and never ramped. Upstream sets a foreground alone while a character burns, then ramps the background from the last fire colour to the input background at the end. On piped text there is no background to lose. On a captured screen that blanks every selection bar and filled panel for the length of the run and then flushes them dark red on the way back, so here the background a cell arrived with simply stays put and the fire plays over it. The other two colour modes are untouched.
type BurnConfig ¶ added in v0.4.0
type BurnConfig struct {
// StartingColor is the unburnt paper: every character wears it from the
// first frame until the fire reaches it.
StartingColor Color
// BurnColors are the colours a character passes through while it burns.
BurnColors []Color
// SmokeChance is how often a character that has finished burning throws
// off a smoke particle. Zero means no smoke.
SmokeChance float64
// FinalGradientStops colour the text once the fire has passed. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
BurnConfig tunes the burn effect.
func DefaultBurnConfig ¶ added in v0.4.0
func DefaultBurnConfig() BurnConfig
DefaultBurnConfig is upstream's default burn.
type Caller ¶
type Caller struct {
// contains filtered or unexported fields
}
Caller identifies what raised an event. Upstream hashes a whole Waypoint dataclass, so two waypoints with the same id and coord collide even across paths; the coord is kept in the key to match that.
func PathCaller ¶
PathCaller keys handlers to a path finishing, starting or holding.
func SceneCaller ¶
SceneCaller keys handlers to a scene finishing or starting.
func WaypointCaller ¶
WaypointCaller keys handlers to a segment ending at a waypoint.
type Canvas ¶
type Canvas struct {
Top int
Right int
Bottom int
Left int
CenterRow int
CenterColumn int
Center Coord
Width int
Height int
TextTop int
TextRight int
TextBottom int
TextLeft int
TextWidth int
TextHeight int
TextCenterRow int
TextCenterColumn int
TextCenter Coord
}
Canvas is the drawable rectangle, in 1-based coordinates with the origin at the bottom left. It also tracks the smaller rectangle the input text actually occupies, which is what gradients are painted across.
func (*Canvas) CoordIsInCanvas ¶
CoordIsInCanvas reports whether a coordinate falls inside the canvas.
func (*Canvas) CoordIsInText ¶
CoordIsInText reports whether a coordinate falls inside the text block.
func (*Canvas) RandomColumn ¶
RandomColumn picks a column, either from the whole canvas or from the text block only.
func (*Canvas) RandomCoord ¶
RandomCoord picks a coordinate. With outsideScope set it picks one cell past a randomly chosen edge, which is where effects launch characters from.
type Character ¶
type Character struct {
// ID is allocation order. It is the canonical ordering key everywhere,
// because effects that walk characters must walk them the same way twice.
ID int
InputSymbol string
InputCoord Coord
IsVisible bool
Layer int
Animation Animation
Motion Motion
// UsesInputColors marks a character that carried its own colours in, which
// the input-colour policies key off.
UsesInputColors bool
// IsFill marks a character the engine invented to pad the canvas rather
// than one that came from the input.
IsFill bool
// Links are the characters this one has been joined to by a spanning
// tree, kept in ascending id order. Upstream holds a Python set here and
// several effects walk it, so the order is pinned rather than left to
// whatever a set happens to yield. LinkCharacters is the only thing that
// writes it.
Links []*Character
// contains filtered or unexported fields
}
Character is one cell of the input, with everything needed to animate it: where it came from, where it is now, what it looks like, and what it does when its motion or animation reaches a milestone.
func (*Character) ClearEvents ¶ added in v0.3.0
func (c *Character) ClearEvents()
ClearEvents drops every action registered on this character. A particle pool calls it when a reused particle must not still be carrying the handlers its previous life registered.
type CharacterFilter ¶
CharacterFilter selects which populations a character query returns.
func InputOnly ¶
func InputOnly() CharacterFilter
InputOnly is the default filter: the characters that came from the input.
type CharacterGroup ¶
type CharacterGroup int
CharacterGroup buckets a character query into ordered groups.
const ( GroupColumnLeftToRight CharacterGroup = iota GroupColumnRightToLeft GroupRowTopToBottom GroupRowBottomToTop GroupDiagonalBottomLeftToTopRight GroupDiagonalTopRightToBottomLeft GroupDiagonalTopLeftToBottomRight GroupDiagonalBottomRightToTopLeft GroupCenterToOutside GroupOutsideToCenter )
The character groupings.
type CharacterSort ¶
type CharacterSort int
CharacterSort orders a character query.
const ( SortTopToBottomLeftToRight CharacterSort = iota SortTopToBottomRightToLeft SortBottomToTopLeftToRight SortBottomToTopRightToLeft SortOutsideRowToMiddle SortMiddleRowToOutside SortRandom )
The character sorts.
type CharacterVisual ¶
type CharacterVisual struct {
Symbol string
Bold bool
Italic bool
Underline bool
Colors ColorPair
// contains filtered or unexported fields
}
CharacterVisual is one character's appearance for one frame, with its SGR string precomputed because the renderer emits it per visible cell per frame.
func NewCharacterVisual ¶
func NewCharacterVisual(symbol string, p VisualParams) *CharacterVisual
NewCharacterVisual builds a visual and formats its SGR string.
func PlainVisual ¶
func PlainVisual(symbol string) *CharacterVisual
PlainVisual is the character with no styling at all.
func (*CharacterVisual) Formatted ¶
func (v *CharacterVisual) Formatted() string
Formatted returns the symbol wrapped in its SGR sequences.
type Clock ¶ added in v0.3.0
type Clock struct {
// contains filtered or unexported fields
}
Clock is the engine's source of time, in seconds.
A handful of effects are written against the wall clock rather than against a frame count: matrix runs its rain for a number of seconds, thunderstorm runs its storm for a number of seconds. Everything else in this engine is reproducible from a seed, and a real clock would take that away from those two: the same seed would give a different number of frames on a fast machine than on a slow one, and a test could not pin either.
So the default is a virtual clock. It advances a fixed step once per Engine.Update, which every effect calls exactly once per frame, and it therefore reports the time the animation would have taken if the host had kept up. A seeded run stays reproducible and "run the rain for eight seconds" still means eight seconds of animation.
The step is 1/frameRate. Set it to the rate the host actually paints at, or a two-second effect will not last two seconds on the screen.
A host that would rather have real elapsed time, and does not mind that the two clock-driven effects stop being reproducible, can put a real clock on the engine instead. Nothing else in the package reads the clock.
func NewRealClock ¶ added in v0.3.0
func NewRealClock() *Clock
NewRealClock builds a clock that reads the machine. An effect driven by it is no longer reproducible from its seed, so use it only when the host wants wall time more than it wants a repeatable run.
func NewVirtualClock ¶ added in v0.3.0
NewVirtualClock builds the default clock: time advances step by step with the frames, not with the machine. A frame rate at or below zero means sixty.
func (*Clock) AdvanceFrame ¶ added in v0.3.0
func (c *Clock) AdvanceFrame()
AdvanceFrame moves a virtual clock on by one frame and does nothing to a real one. Engine.Update calls it, so an effect never has to; calling it as well would run the clock at twice the frame rate.
func (*Clock) Elapsed ¶ added in v0.3.0
Elapsed is seconds since the run started, upstream's time.monotonic().
type Color ¶
Color is a 24-bit RGB colour. Upstream also carries the original constructor argument so that Color(255) and Color("ffffff") hash apart; that only mattered for Python dict keying during parity checks, so it is dropped here.
func AdjustColorBrightness ¶ added in v0.2.0
AdjustColorBrightness scales a colour's lightness, keeping its hue and saturation. A factor below 1 darkens and above 1 brightens.
It is a hand-rolled RGB to HSL round trip rather than a library conversion, because that is what upstream does and the results differ in the last unit of each channel. Effects that fade a character and brighten it back are tuned to these numbers. Note this rounds half to even at the end, unlike ShiftColorTowards which truncates.
func MustParseColor ¶
MustParseColor is ParseColor for compile-time constants. It panics on a bad string, so only pass literals.
func ParseColor ¶
ParseColor reads a colour from a hex string, with or without a leading hash.
func ShiftColorTowards ¶
ShiftColorTowards interpolates between two colours.
Upstream truncates back to an integer channel rather than rounding, so a shift lands one value low most of the time. Kept for the same reason as the gradient floor division.
type Coord ¶
Coord is a 1-based canvas coordinate. Column grows right and row grows up, so the origin sits at the bottom left, as it does upstream.
func ExtrapolateAlongRay ¶ added in v0.2.0
ExtrapolateAlongRay returns the coordinate reached by carrying on past target, along the line from origin, by offsetFromTarget cells.
The line length here is the raw one, with no row doubling, unlike most of this file. That is upstream's choice and effects are tuned to it.
func FindCoordOnBezierCurve ¶
FindCoordOnBezierCurve runs De Casteljau over any number of control points.
func FindCoordOnLine ¶
FindCoordOnLine interpolates between two coords and rounds the result.
func FindCoordsInCircle ¶ added in v0.2.0
FindCoordsInCircle returns every coordinate inside an ellipse centred on the given coord.
Upstream calls this a circle and builds an ellipse: the horizontal semi-axis is the diameter and the vertical one is half of it. That is the terminal cell aspect correction done in the shape rather than in the distance, and effects are tuned to the shape it actually produces.
func FindCoordsInRect ¶ added in v0.2.0
FindCoordsInRect returns every coordinate in the square block reaching distance cells out from the origin. A distance of zero returns nothing.
func FindCoordsOnCircle ¶
FindCoordsOnCircle returns points on a circle around origin. The column offset is doubled so the circle looks round in a terminal cell grid.
func FindCoordsOnRect ¶ added in v0.2.0
FindCoordsOnRect returns the perimeter of a rectangle. Either half-dimension being zero returns nothing.
type CoordColorMap ¶
CoordColorMap maps canvas coordinates to gradient colours.
type Crumble ¶ added in v0.4.0
type Crumble struct {
// contains filtered or unexported fields
}
Crumble breaks the text up and puts it back. Every character dims, turns to dust, falls to the bottom of the canvas, gets sucked out through the top, and then flies home and flashes white as it re-forms.
This effect passes over the screen rather than assembling it, so every character is visible from the first frame, wearing a dimmed version of the colour it will settle back to. That is upstream's own behaviour here, not a deviation: crumble starts from a picture that is already on screen, which is exactly what DynamicExistingColors wants.
func NewCrumble ¶ added in v0.4.0
func NewCrumble(config CrumbleConfig) *Crumble
NewCrumble builds the effect.
type CrumbleConfig ¶ added in v0.4.0
type CrumbleConfig struct {
// FinalGradientStops colour the text once it reforms. They are ignored
// when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
CrumbleConfig tunes the crumble effect.
func DefaultCrumbleConfig ¶ added in v0.4.0
func DefaultCrumbleConfig() CrumbleConfig
DefaultCrumbleConfig is upstream's default crumble.
type Decrypt ¶
type Decrypt struct {
// contains filtered or unexported fields
}
Decrypt types the text out as ciphertext, then resolves it character by character.
type DecryptConfig ¶
type DecryptConfig struct {
// TypingSpeed is how many characters appear per typing tick.
TypingSpeed int
// CiphertextColors are picked at random per character for the scrambled
// phase.
CiphertextColors []Color
// FinalGradientStops colour the text once it resolves. They are ignored
// when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
DecryptConfig tunes the decrypt effect.
func DefaultDecryptConfig ¶
func DefaultDecryptConfig() DecryptConfig
DefaultDecryptConfig is upstream's default decrypt.
type Descriptor ¶
type Descriptor struct {
Name string
Description string
New Factory
// NeedsFillCharacters says the effect animates the empty cells of the
// canvas as well as the input, so the terminal must be built with
// MakeFillCharacters set.
//
// It is declared here rather than discovered in Build because the
// terminal is built before the effect is, and a fill character cannot be
// added afterwards. An effect that queries InnerFill or OuterFill without
// setting this gets an empty result and quietly animates nothing, which
// is the failure this field exists to prevent.
NeedsFillCharacters bool
// Origin credits an effect this package wrote rather than ported.
//
// A port leaves it empty. Ports are credited in NOTICE, which maps every
// file here to the ttfx source and the TerminalTextEffects source it was
// translated from, and that is the only credit a port needs.
//
// An effect that was not translated has no line to write there, so it
// carries its credit here instead: where its material came from, in one
// line, in the effect's own registration where the person adding it
// cannot avoid deciding. An empty Origin is therefore a claim in itself,
// that this effect is a translation and NOTICE says of what.
//
// catalogue_test.go holds both halves to their word.
Origin string
}
Descriptor is a registered effect: its name, one line about what it does, how to build one, and what it needs from the terminal before it can build.
func Descriptors ¶
func Descriptors() []Descriptor
Descriptors lists every registered effect with its description, sorted by name.
type Easing ¶
type Easing int
Easing names one of the standard easing curves. Ported from ttfx src/utils/easing.rs, which ports TerminalTextEffects utils/easing.py.
const ( Linear Easing = iota InSine OutSine InOutSine InQuad OutQuad InOutQuad InCubic OutCubic InOutCubic InQuart OutQuart InOutQuart InQuint OutQuint InOutQuint InExpo OutExpo InOutExpo InCirc OutCirc InOutCirc InBack OutBack InOutBack InElastic OutElastic InOutElastic InBounce OutBounce InOutBounce )
The easing curves. Linear is the zero value, so a Path with no easing set moves at a constant rate.
func ParseEasing ¶
ParseEasing looks up an easing curve by its upstream name.
type Effect ¶
Effect is one animation. Build runs once and sets up every character's scenes and paths; Advance then runs one frame at a time until it reports that the effect is over.
Advance does not return the frame. The caller reads it from the engine with Frame or FrameRows, so an effect never has to care whether its host wants an ANSI string or a cell grid.
type Engine ¶
type Engine struct {
Terminal *Terminal
Rng *Rng
// Clock is the source of time for the few effects written against
// seconds rather than frames. NewEngine installs a virtual one so those
// effects stay reproducible from the seed; see clock.go.
Clock *Clock
// contains filtered or unexported fields
}
Engine is the mutable world an effect runs in: the terminal, the random source, and the set of characters that still have work to do.
Every stepping routine that can raise an event lives here rather than on the character, because an event action runs inline at the point it is raised and may reach back into the same structures being stepped. Ported from ttfx src/engine/ctx.rs.
func NewEngine ¶
NewEngine builds an engine over a terminal. Its clock is a virtual one running at sixty frames a second; set Engine.Clock if the host paints at a different rate, or wants real elapsed time.
func (*Engine) ActivatePath ¶
ActivatePath starts a path, splicing in a segment from wherever the character currently stands to the path's first waypoint.
func (*Engine) ActivateScene ¶
ActivateScene starts a scene. It resumes rather than restarts: a scene that was part way through picks up where it stopped.
func (*Engine) ActiveCharacters ¶
ActiveCharacters returns the active set in ascending id order. The slice is reused between calls.
func (*Engine) ActiveCount ¶
ActiveCount is how many characters are still animating.
func (*Engine) ChainPaths ¶
ChainPaths makes each path activate the next one when it completes.
func (*Engine) Deactivate ¶
Deactivate removes a character from the active set.
func (*Engine) DeactivateScene ¶
DeactivateScene stops a scene. An empty id stops whatever is running.
func (*Engine) FrameRows ¶
func (e *Engine) FrameRows() [][]*CharacterVisual
FrameRows renders the current state as rows of visuals, top row first.
func (*Engine) MotionMove ¶
MotionMove advances the character along its active path by one step.
func (*Engine) StepAnimation ¶
StepAnimation advances the character's active scene by one tick.
func (*Engine) Update ¶
func (e *Engine) Update()
Update ticks every active character, then drops the ones that finished, then moves the clock on by one frame.
The clock moves here rather than in Frame because an effect calls Update exactly once per frame, while a host may read Frame twice or not at all.
type ErrorCorrect ¶ added in v0.4.0
type ErrorCorrect struct {
// contains filtered or unexported fields
}
ErrorCorrect starts with the whole picture on screen and some of it transposed. It then works through the misplaced pairs, flashing each one red, wiping it into a block, flying the two characters past each other and settling them into their own cells.
The picture is there from the first frame in every colour mode, so this is an effect that passes over the screen rather than one that assembles it. Upstream already shows every character during the build, so it needs none of the reveal-from-frame-one handling a sweep like waves does.
func NewErrorCorrect ¶ added in v0.4.0
func NewErrorCorrect(config ErrorCorrectConfig) *ErrorCorrect
NewErrorCorrect builds the effect.
func (*ErrorCorrect) Advance ¶ added in v0.4.0
func (x *ErrorCorrect) Advance(e *Engine) bool
Advance releases one pair every SwapDelay frames and reports whether the effect is still going.
func (*ErrorCorrect) Build ¶ added in v0.4.0
func (x *ErrorCorrect) Build(e *Engine) error
Build shows the whole picture, picks the pairs that will start transposed, and gives each of them the path and the scenes that put it back.
type ErrorCorrectConfig ¶ added in v0.4.0
type ErrorCorrectConfig struct {
// ErrorPairs is the share of the characters that start in the wrong
// place, between 0 and 1. Each pair takes two characters, so 0.1 over a
// hundred characters makes ten pairs and misplaces twenty of them.
ErrorPairs float64
// SwapDelay is how many frames pass between one pair being released and
// the next.
SwapDelay int
// ErrorColor marks a character that is in the wrong place.
ErrorColor Color
// CorrectColor marks a character that has just been put right. It is the
// colour the closing ramp starts from.
CorrectColor Color
// MovementSpeed is how fast a character travels back to its own cell.
MovementSpeed float64
// FinalGradientStops colour the text once every pair is home. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
ErrorCorrectConfig tunes the errorcorrect effect.
func DefaultErrorCorrectConfig ¶ added in v0.4.0
func DefaultErrorCorrectConfig() ErrorCorrectConfig
DefaultErrorCorrectConfig is upstream's default errorcorrect.
type EtchPattern ¶ added in v0.4.0
type EtchPattern int
EtchPattern picks the order the laser etches characters in.
const ( // EtchAlgorithm cuts along a recursive backtracker's walk over the text // block, which gives the laser long corridors and dead ends rather than a // tidy sweep. This is the default and the only pattern that etches. EtchAlgorithm EtchPattern = iota // EtchGroup is upstream's grouped ordering, and it etches nothing. // // Upstream parses the option into a CharacterGroup member and then tests // that member against the enum's member *names*, which never matches. The // grouped branch is unreachable, no character is ever queued, and the // effect emits a single frame. ttfx reproduced that after checking it // against the reference build, and so does this. // // ttfx carries the requested group alongside the variant. Nothing reads // it, so this does not: the outcome is the same whichever group is asked // for. EtchGroup )
The etch patterns.
type Event ¶
type Event int
Event is something a character's motion or animation reached. Effects hang actions off these, which is how a character chains one scene or path into the next without the effect polling for it.
type ExistingColorHandling ¶
type ExistingColorHandling int
ExistingColorHandling says what an effect does with colours the input already carried.
const ( // IgnoreExistingColors throws the input colours away and uses the // effect's own gradient. This is upstream's default. IgnoreExistingColors ExistingColorHandling = iota // DynamicExistingColors resolves every character back to the colour it // arrived with. A screen saver over a captured screen wants this: the // screen reassembles in its own colours. DynamicExistingColors // AlwaysExistingColors pins every frame to the input colour, so the // effect animates shape but never colour. AlwaysExistingColors )
The three input-colour policies.
type Expand ¶ added in v0.4.0
type Expand struct {
// contains filtered or unexported fields
}
Expand stacks every character on the middle of the canvas and moves it out to where it belongs, colouring it as it goes.
This effect ASSEMBLES the screen rather than passing over it, so it does not show the picture in place on the first frame. Upstream makes every character visible during the build, all of them piled on the centre cell, and the picture only exists once they have travelled. Under DynamicExistingColors that is the right behaviour unchanged: the screen collapses to a point and grows back into itself.
func NewExpand ¶ added in v0.4.0
func NewExpand(config ExpandConfig) *Expand
NewExpand builds the effect.
type ExpandConfig ¶ added in v0.4.0
type ExpandConfig struct {
// ExpandEasing shapes the travel from the middle of the canvas outwards.
// The default starts and ends slowly, so the picture swells rather than
// bursts.
ExpandEasing Easing
// MovementSpeed is how fast a character travels to where it belongs.
MovementSpeed float64
// FinalGradientStops colour the text once it is in place. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
ExpandConfig tunes the expand effect.
func DefaultExpandConfig ¶ added in v0.4.0
func DefaultExpandConfig() ExpandConfig
DefaultExpandConfig is upstream's default expand.
type ExpandDirection ¶ added in v0.4.0
type ExpandDirection int
ExpandDirection is the axis middleout spreads along before it expands out to the rest of the canvas.
The names carry an Expand prefix because Vertical and Horizontal already name the axes of a GradientDirection.
const ( // ExpandVertical spreads the text across the centre row first, then // expands up and down. ExpandVertical ExpandDirection = iota // ExpandHorizontal spreads the text down the centre column first, then // expands left and right. ExpandHorizontal )
The two expansion axes.
func ParseExpandDirection ¶ added in v0.4.0
func ParseExpandDirection(name string) (ExpandDirection, bool)
ParseExpandDirection looks up an expansion axis by its upstream name.
type Factory ¶
type Factory func() Effect
Factory builds a fresh instance of an effect with its default settings.
type Fireworks ¶ added in v0.4.0
type Fireworks struct {
// contains filtered or unexported fields
}
Fireworks packs the characters into shells, launches each shell from the bottom of the canvas, bursts it, and lets the pieces fall into the cells they belong in.
It assembles the screen rather than passing over it. Every character starts off its own cell, at the bottom edge, and is hidden until its shell is launched. That holds under DynamicExistingColors too: showing the picture from the first frame would leave the shells climbing over the finished screen they are supposed to be delivering.
func NewFireworks ¶ added in v0.4.0
func NewFireworks(config FireworksConfig) *Fireworks
NewFireworks builds the effect.
type FireworksConfig ¶ added in v0.4.0
type FireworksConfig struct {
// ExplodeAnywhere lets a shell burst anywhere on the canvas. Left off, a
// shell bursts at or above the row its first character belongs on, so the
// bursts stay clear of the settled text.
ExplodeAnywhere bool
// FireworkColors are picked at random, one per shell.
FireworkColors []Color
// FireworkSymbol is the glyph a character wears while it climbs.
FireworkSymbol string
// FireworkVolume is how many characters go into one shell, as a fraction
// of the total. It is at least one character.
FireworkVolume float64
// LaunchDelay is roughly how many frames pass between one shell and the
// next. Each wait is scaled by a random half to one and a half.
LaunchDelay int
// ExplodeDistance is how far a character flies from the burst point, as a
// fraction of the canvas width. It is capped at fifteen cells.
ExplodeDistance float64
// FinalGradientStops colour the text once it has fallen into place. They
// are ignored when the engine is set to resolve to the input's own
// colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
FireworksConfig tunes the fireworks effect.
func DefaultFireworksConfig ¶ added in v0.4.0
func DefaultFireworksConfig() FireworksConfig
DefaultFireworksConfig is upstream's default fireworks.
type Frame ¶
type Frame struct {
Visual *CharacterVisual
Duration int
// contains filtered or unexported fields
}
Frame is one visual held for a number of ticks.
type Gradient ¶
type Gradient struct {
Spectrum []Color
}
Gradient is a precomputed list of colours between a set of stops.
func NewGradient ¶
NewGradient builds a spectrum from stops and a per-pair step count.
The channel deltas use integer floor division rather than a float lerp, and the exact end stop is appended after each pair. That is upstream's arithmetic. It biases every ramp slightly and gives the spectrum its characteristic banding, so it is reproduced rather than corrected.
func NewGradientSteps ¶
NewGradientSteps is NewGradient with one step count for every pair, which is how nearly every effect calls it.
func (*Gradient) BuildCoordinateColorMapping ¶
func (g *Gradient) BuildCoordinateColorMapping(minRow, maxRow, minColumn, maxColumn int, direction GradientDirection) (CoordColorMap, error)
BuildCoordinateColorMapping paints a gradient across a rectangle.
func (*Gradient) ColorAtFraction ¶
ColorAtFraction picks the spectrum entry covering a position in [0,1].
type GradientDirection ¶
type GradientDirection int
GradientDirection is the axis a coordinate colour mapping runs along.
const ( Vertical GradientDirection = iota Horizontal Radial Diagonal )
The gradient axes.
func ParseGradientDirection ¶
func ParseGradientDirection(name string) (GradientDirection, bool)
ParseGradientDirection looks up a gradient axis by its upstream name.
type Highlight ¶ added in v0.4.0
type Highlight struct {
// contains filtered or unexported fields
}
Highlight sweeps a band of brighter colour across the screen. Nothing moves and nothing is hidden: every character is on screen from the first frame wearing the colour it settles at, and the band brightens each one in turn as it passes over.
Upstream drops the map it builds from character to final colour without ever reading it, and the Rust port keeps it only to stay faithful. It is left out here because a field nothing reads is not faithfulness, it is dead weight.
func NewHighlight ¶ added in v0.4.0
func NewHighlight(config HighlightConfig) *Highlight
NewHighlight builds the effect.
type HighlightConfig ¶ added in v0.4.0
type HighlightConfig struct {
// HighlightBrightness is how much brighter the middle of the band is than
// the colour the character settles at. It scales lightness, so a value
// above 1 brightens and a value below 1 darkens.
HighlightBrightness float64
// HighlightDirection is the axis the band travels along. The characters
// are grouped by it and released one group at a time.
HighlightDirection CharacterGroup
// HighlightWidth is how many frames the band holds its brightest colour.
// A wider band spends longer at full brightness, so it reads as a broader
// stripe of light. It must be at least 1.
HighlightWidth int
// FinalGradientStops colour the text the band travels over. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
HighlightConfig tunes the highlight effect.
func DefaultHighlightConfig ¶ added in v0.4.0
func DefaultHighlightConfig() HighlightConfig
DefaultHighlightConfig is upstream's default highlight.
type InputCell ¶
type InputCell struct {
// Symbol is the grapheme cluster in the cell. An empty string is a blank.
Symbol string
Fg Color
HasFg bool
Bg Color
HasBg bool
Bold bool
}
InputCell is one cell of a screen capture handed to the engine.
type LaserEtch ¶ added in v0.4.0
type LaserEtch struct {
// contains filtered or unexported fields
}
LaserEtch cuts the text onto the screen. A beam swings in from off the bottom left corner, stops on one character at a time in the order a recursive backtracker walked the text block, and leaves that character glowing and cooling behind it. Every stop throws a spark that falls to the bottom of the canvas and burns out.
func NewLaserEtch ¶ added in v0.4.0
func NewLaserEtch(config LaserEtchConfig) *LaserEtch
NewLaserEtch builds the effect.
type LaserEtchConfig ¶ added in v0.4.0
type LaserEtchConfig struct {
// EtchPattern is the order characters are etched in. See EtchPattern:
// only EtchAlgorithm etches.
EtchPattern EtchPattern
// EtchSpeed is how many characters are etched in one go, and EtchDelay is
// how many frames pass before the next go. Together they set the pace.
EtchSpeed int
EtchDelay int
// CoolGradientStops colour a character as it cools from laser-hot back to
// its settled colour.
CoolGradientStops []Color
// LaserGradientStops colour the beam itself. The gradient loops and each
// cell of the beam starts one step further along it, so the colour runs
// up the beam.
LaserGradientStops []Color
// SparkGradientStops colour a spark as it cools on the way down, and
// SparkCoolingFrames is how long each of those colours is held. Raise it
// to cool sparks more slowly.
SparkGradientStops []Color
SparkCoolingFrames int
// FinalGradientStops colour the text once it has cooled. They are ignored
// when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
// FinalGradientFrames is carried for parity with upstream's options and
// changes nothing. Upstream declares it and never reads it: laseretch has
// no separate final-gradient scene, because the cool gradient already
// ends on the final colour.
FinalGradientFrames int
}
LaserEtchConfig tunes the laseretch effect.
func DefaultLaserEtchConfig ¶ added in v0.4.0
func DefaultLaserEtchConfig() LaserEtchConfig
DefaultLaserEtchConfig is upstream's default laseretch.
type Matrix ¶ added in v0.4.0
type Matrix struct {
// contains filtered or unexported fields
}
Matrix rains characters down the screen for a while, fills the screen with them, then resolves the input out of the fill a few characters at a time.
func NewMatrix ¶ added in v0.4.0
func NewMatrix(config MatrixConfig) *Matrix
NewMatrix builds the effect.
type MatrixConfig ¶ added in v0.4.0
type MatrixConfig struct {
// HighlightColor is the colour of the character at the bottom of a
// falling column, the drop's leading edge.
HighlightColor Color
// RainColorGradient is the ramp the rest of a column is coloured from.
// Colours are picked from it at random.
RainColorGradient []Color
// RainSymbols are the glyphs the rain is drawn with.
RainSymbols []string
// RainFallDelayLow and RainFallDelayHigh bound how many frames a column
// waits between rows. A column picks one value and keeps it.
RainFallDelayLow int
RainFallDelayHigh int
// RainColumnDelayLow and RainColumnDelayHigh bound how many frames pass
// between starting new columns.
RainColumnDelayLow int
RainColumnDelayHigh int
// RainTime is how many seconds the rain falls for before the columns fill
// the screen and the text resolves. Zero means the rain never ends on its
// own.
RainTime int
// SymbolSwapChance and ColorSwapChance are the per-frame odds that a
// character already in the rain changes its glyph or its colour.
SymbolSwapChance float64
ColorSwapChance float64
// ResolveDelay is how many frames pass between resolving one group of
// characters and the next. Raise it to slow the ending down.
ResolveDelay int
// FinalGradientStops colour the text once it resolves. They are ignored
// when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientFrames int
FinalGradientDirection GradientDirection
}
MatrixConfig tunes the matrix effect.
func DefaultMatrixConfig ¶ added in v0.4.0
func DefaultMatrixConfig() MatrixConfig
DefaultMatrixConfig is upstream's default matrix.
type Middleout ¶ added in v0.4.0
type Middleout struct {
// contains filtered or unexported fields
}
Middleout collapses the whole input onto the centre of the canvas, spreads it out along one axis into a single line, and then expands that line back out until every character is home.
func NewMiddleout ¶ added in v0.4.0
func NewMiddleout(config MiddleoutConfig) *Middleout
NewMiddleout builds the effect.
func (*Middleout) Advance ¶ added in v0.4.0
Advance runs one frame. When the first expansion has finished it starts the second one on every character at once, and reports whether anything is still moving.
type MiddleoutConfig ¶ added in v0.4.0
type MiddleoutConfig struct {
// StartingColor is what every character wears while it is stacked on the
// centre and spreading out along the first axis. The closing ramp starts
// from it.
StartingColor Color
// ExpandDirection is the axis the text spreads along first.
ExpandDirection ExpandDirection
// CenterMovementSpeed is how fast a character travels during the first
// expansion, in cells per frame.
CenterMovementSpeed float64
// FullMovementSpeed is how fast it travels during the second one.
FullMovementSpeed float64
// CenterEasing shapes the first expansion, FullEasing the second.
CenterEasing Easing
FullEasing Easing
// FinalGradientStops colour the text once it has arrived. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
MiddleoutConfig tunes the middleout effect.
func DefaultMiddleoutConfig ¶ added in v0.4.0
func DefaultMiddleoutConfig() MiddleoutConfig
DefaultMiddleoutConfig is upstream's default middleout.
type Motion ¶
type Motion struct {
CurrentCoord Coord
PreviousCoord Coord
// contains filtered or unexported fields
}
Motion is one character's movement state.
func (*Motion) ClearPaths ¶ added in v0.3.0
func (m *Motion) ClearPaths()
ClearPaths removes every path from the character and stops whatever was running. Upstream clears the path table without touching the active path reference; this clears both, because a reference to a path that no longer exists leaves MovementIsComplete false forever and the character never leaves the active set.
func (*Motion) DeactivatePath ¶
DeactivatePath stops the named path. An empty id stops whatever is running.
func (*Motion) MovementIsComplete ¶
MovementIsComplete reports whether the character has no path running.
func (*Motion) NewPath ¶
func (m *Motion) NewPath(id string, opts PathOptions) (*Path, error)
NewPath registers a path. An empty id gets an auto-allocated one.
func (*Motion) SetCoordinate ¶
SetCoordinate teleports the character without touching any path.
type OrbittingVolley ¶ added in v0.4.0
type OrbittingVolley struct {
// contains filtered or unexported fields
}
OrbittingVolley circles four launchers around the edge of the canvas and fires the characters out of them a volley at a time. Each character flies from whichever launcher holds it to the cell it came from.
func NewOrbittingVolley ¶ added in v0.4.0
func NewOrbittingVolley(config OrbittingVolleyConfig) *OrbittingVolley
NewOrbittingVolley builds the effect.
func (*OrbittingVolley) Advance ¶ added in v0.4.0
func (o *OrbittingVolley) Advance(e *Engine) bool
Advance moves the launchers, fires a volley when the delay runs out, and reports whether the effect is still going. The last frame it produces is the one where the launchers are hidden, so the text is left on its own.
func (*OrbittingVolley) Build ¶ added in v0.4.0
func (o *OrbittingVolley) Build(e *Engine) error
Build gives every character the path home that a launcher will send it along, then places the four launchers and deals the characters out between them from the middle of the text outwards.
type OrbittingVolleyConfig ¶ added in v0.4.0
type OrbittingVolleyConfig struct {
// TopLauncherSymbol and the three that follow are the glyphs the four
// launchers are drawn with. The top one is the launcher that actually
// moves; the other three are placed from its progress each frame.
TopLauncherSymbol string
RightLauncherSymbol string
BottomLauncherSymbol string
LeftLauncherSymbol string
// LauncherMovementSpeed is how fast the top launcher crosses the canvas.
LauncherMovementSpeed float64
// CharacterMovementSpeed is how fast a fired character flies to its home.
CharacterMovementSpeed float64
// VolleySize is the share of the input each volley fires, split across the
// four launchers. One character per launcher is the floor.
VolleySize float64
// LaunchDelay is how many frames pass between volleys.
LaunchDelay int
// CharacterEasing shapes a fired character's flight.
CharacterEasing Easing
// FinalGradientStops colour the text once it lands. They are ignored when
// the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
OrbittingVolleyConfig tunes the orbittingvolley effect.
func DefaultOrbittingVolleyConfig ¶ added in v0.4.0
func DefaultOrbittingVolleyConfig() OrbittingVolleyConfig
DefaultOrbittingVolleyConfig is upstream's default orbittingvolley.
type Overflow ¶ added in v0.4.0
type Overflow struct {
// contains filtered or unexported fields
}
Overflow scrolls the text up the canvas in the wrong order, over and over, and then scrolls the real rows in behind it so the picture arrives from the bottom edge.
This effect assembles the screen rather than passing over it, so every character stays hidden until the row carrying it enters from the bottom. That holds under every colour policy, DynamicExistingColors included: showing the picture up front would leave the scroll nothing to deliver, and the copies would scrape across a screen that was already finished.
func NewOverflow ¶ added in v0.4.0
func NewOverflow(config OverflowConfig) *Overflow
NewOverflow builds the effect.
type OverflowConfig ¶ added in v0.4.0
type OverflowConfig struct {
// OverflowGradientStops colour the rows while they are scrolling past.
// The gradient runs up the canvas, so a row changes colour as it climbs.
OverflowGradientStops []Color
// OverflowCyclesLow and OverflowCyclesHigh bound how many times the text
// is scrambled and scrolled past before the real rows arrive. Setting
// OverflowCyclesHigh to zero skips the scramble entirely.
OverflowCyclesLow int
OverflowCyclesHigh int
// OverflowSpeed is the most rows that can be released in one frame.
OverflowSpeed int
// FinalGradientStops colour the text once it lands. They are ignored when
// the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
OverflowConfig tunes the overflow effect.
func DefaultOverflowConfig ¶ added in v0.4.0
func DefaultOverflowConfig() OverflowConfig
DefaultOverflowConfig is upstream's default overflow.
type ParticlePool ¶ added in v0.3.0
type ParticlePool struct {
// Symbols is what a new particle can look like. Emit picks one at random
// unless it is given a symbol.
Symbols []string
// MaxSize caps how many particles the pool will ever create. Zero means
// no cap. Once the cap is reached and the free list is empty, Emit
// returns nil rather than growing.
MaxSize int
// Coord is where a newly created particle is placed before anything moves
// it. Emit moves it, so this only matters for the frame a particle is
// made in.
Coord Coord
// Particles is every particle the pool owns, free or in flight, in the
// order they were created. An effect that has to register something on
// each of them walks this.
Particles []*Character
// contains filtered or unexported fields
}
ParticlePool recycles characters that are not part of the input: sparks, smoke, raindrops. An effect that throws off thousands of short-lived characters would otherwise allocate a thousand more every second and never free any of them, because a character lives on the terminal for the whole run.
A particle goes round a loop. Emit takes one off the free list, puts it where the effect wants it, lets the effect give it a path and a scene, shows it and makes it active. When it is finished, Reclaim hides it and puts it back on the free list. Reclaim usually runs from an event: ReclaimOnEvent wires it to the scene or path whose completion means the particle is spent.
pool, err := NewParticlePool([]string{"*", "."}, 2000, Coord{}, initSpark)
pool.Preallocate(e, 2000)
...
spark := pool.Emit(e, origin, "", true, ParticleReset{}, func(e *Engine, ch *Character) {
// give it a path and a scene, then activate them
})
Ported from ttfx src/engine/particles.rs.
func NewParticlePool ¶ added in v0.3.0
func NewParticlePool(symbols []string, maxSize int, coord Coord, initializer func(e *Engine, ch *Character)) (*ParticlePool, error)
NewParticlePool builds a pool. maxSize of zero means no cap.
initializer runs once on each particle the pool creates, and never on one it reuses. It is where the effect builds the scenes a particle needs for its whole life, so that emitting one is cheap. It may be nil.
Upstream passes the initializer to every call that might create a particle instead of holding it. Every effect in the catalogue passes the same closure to all of them, and passing two different ones would mean particles that behave differently depending on whether the pool happened to be empty, so this holds it once.
func (*ParticlePool) Acquire ¶ added in v0.3.0
func (p *ParticlePool) Acquire(e *Engine, symbol string, reset ParticleReset) *Character
Acquire takes a particle off the free list, or creates one if the free list is empty and the cap allows. It returns nil when the pool is capped out.
An empty symbol keeps whatever the particle already looks like, which for a new one is a symbol drawn at random from Symbols. A given symbol replaces it.
The particle is not placed, shown or activated: Acquire is for an effect that wants to do all of that itself. Emit is the usual call.
func (*ParticlePool) AvailableCount ¶ added in v0.3.0
func (p *ParticlePool) AvailableCount() int
AvailableCount is how many particles are on the free list.
func (*ParticlePool) Emit ¶ added in v0.3.0
func (p *ParticlePool) Emit(e *Engine, origin Coord, symbol string, visible bool, reset ParticleReset, onEmit func(e *Engine, ch *Character)) *Character
Emit acquires a particle, puts it at origin, hands it to onEmit, then shows it and makes it active. It returns nil when the pool is capped out and the free list is empty, which an effect throwing off decoration can ignore.
onEmit is where the effect gives the particle the path and scene for this flight and activates them. It may be nil.
func (*ParticlePool) Extend ¶ added in v0.3.0
func (p *ParticlePool) Extend(particles ...*Character)
Extend adopts characters the effect made itself. They join the free list as they are, with no reset, so whatever the effect set up on them survives.
func (*ParticlePool) Len ¶ added in v0.3.0
func (p *ParticlePool) Len() int
Len is how many particles the pool owns in total, free and in flight.
func (*ParticlePool) Preallocate ¶ added in v0.3.0
func (p *ParticlePool) Preallocate(e *Engine, count int) error
Preallocate creates count particles up front and puts them on the free list, so the first burst of emissions does not build characters mid-frame.
func (*ParticlePool) Reclaim ¶ added in v0.3.0
func (p *ParticlePool) Reclaim(e *Engine, ch *Character, hide, deactivate bool)
Reclaim puts a particle back on the free list. Reclaiming one that is already there does nothing, so an effect may call it from more handlers than will actually fire.
func (*ParticlePool) ReclaimOnEvent ¶ added in v0.3.0
func (p *ParticlePool) ReclaimOnEvent(ch *Character, event Event, from Caller, hide, deactivate bool)
ReclaimOnEvent registers Reclaim against an event, which is how a particle puts itself back once its scene or path finishes.
pool.ReclaimOnEvent(spark, SceneComplete, SceneCaller("glow"), true, true)
Registering it again on the same particle and event is harmless: reclaiming twice does nothing the second time. Upstream reaches this through a callback id table because Rust cannot hold the closure; here it is the closure.
type ParticleReset ¶ added in v0.3.0
type ParticleReset struct {
// KeepPaths leaves the particle's paths in place. Upstream's
// clear_paths=False.
KeepPaths bool
// ClearScenes throws the particle's scenes away as well. Upstream's
// clear_scenes=True. An effect that sets this pays to rebuild the scenes
// on every emission.
ClearScenes bool
// ClearEvents drops the actions registered on the particle. Upstream's
// clear_events=True. Set it when the effect registers a fresh handler per
// emission, or they accumulate over the run.
ClearEvents bool
// KeepActivePath leaves the particle travelling. Upstream's
// deactivate_path=False.
KeepActivePath bool
// KeepActiveScene leaves the particle's scene running. Upstream's
// deactivate_scene=False.
KeepActiveScene bool
// ResetAppearance puts the particle back to its input symbol with no
// colours. Upstream's reset_appearance=True.
ResetAppearance bool
}
ParticleReset says how much of a particle's previous life to wipe when it is handed out again.
The zero value is upstream's default, and it is what every effect in the catalogue uses: the particle's paths are thrown away and its running path and scene are stopped, while its scenes are kept because building them again per emission is the cost the pool exists to avoid.
Three of these fields are inverted against upstream, which names them clear_paths, deactivate_path and deactivate_scene and defaults all three to true. A Go struct defaults to false, so a faithful set of names would make the zero value mean "reset nothing" and quietly hand out a particle still flying along its last path. Inverting them puts upstream's default on the zero value, and asking for the non-default now has to be written down.
type Path ¶
type Path struct {
ID string
Speed float64
Ease Easing
HasEase bool
Layer int
HasLayer bool
HoldTime int
Loop bool
Segments []Segment
Waypoints []Waypoint
// contains filtered or unexported fields
}
Path is an ordered set of waypoints a character travels along at a fixed speed, optionally eased over the whole path.
type PathOptions ¶
type PathOptions struct {
Speed float64
Ease Easing
HasEase bool
Layer int
HasLayer bool
HoldTime int
Loop bool
}
PathOptions are the knobs NewPath accepts.
type PopCondition ¶ added in v0.4.0
type PopCondition int
PopCondition decides when a floating bubble bursts.
const ( // PopOnRow bursts a bubble once it reaches the lowest input row of the // characters riding it, so each group pops near where it belongs. PopOnRow PopCondition = iota // PopOnBottom carries every bubble down to the bottom of the canvas // first. PopOnBottom // PopAnywhere is PopOnBottom with a small chance of bursting on any // frame along the way. PopAnywhere )
The three pop conditions. Row is first so the zero value is upstream's default.
func ParsePopCondition ¶ added in v0.4.0
func ParsePopCondition(name string) (PopCondition, bool)
ParsePopCondition looks up a pop condition by its upstream name.
type Pour ¶ added in v0.4.0
type Pour struct {
// contains filtered or unexported fields
}
Pour empties the text into the canvas one row or column at a time. Every character starts off the far edge, travels to where it belongs, and ramps from the starting colour to its final one on the way.
This effect assembles the screen rather than passing over it, so every character stays hidden until it is released. That holds under every colour policy, including DynamicExistingColors: showing the picture up front would leave nothing for the pour to fill in.
type PourConfig ¶ added in v0.4.0
type PourConfig struct {
// Direction is the edge the text pours towards.
Direction PourDirection
// PourSpeed is how many characters are released per tick. Raise it to
// pour faster.
PourSpeed int
// MovementSpeedLow and MovementSpeedHigh bound each character's travel
// speed.
MovementSpeedLow float64
MovementSpeedHigh float64
// Gap is how many frames to wait between releases.
Gap int
// StartingColor is the colour a character wears while it is falling,
// before its closing ramp begins.
StartingColor Color
// FinalGradientStops colour the text once it lands. They are ignored when
// the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientFrames int
FinalGradientDirection GradientDirection
// MovementEasing shapes the travel. The default accelerates towards the
// resting place.
MovementEasing Easing
}
PourConfig tunes the pour effect.
func DefaultPourConfig ¶ added in v0.4.0
func DefaultPourConfig() PourConfig
DefaultPourConfig is upstream's default pour.
type PourDirection ¶ added in v0.4.0
type PourDirection int
PourDirection is the way the text pours: the edge it falls towards.
const ( // PourDown fills the bottom row first, from characters entering at the // top of the canvas. PourDown PourDirection = iota // PourUp fills the top row first, from characters entering at the bottom. PourUp // PourLeft fills the left column first, from characters entering at the // right edge. PourLeft // PourRight fills the right column first, from characters entering at the // left edge. PourRight )
The four pour directions.
type PrimsSimple ¶ added in v0.3.0
type PrimsSimple struct {
// LimitToTextBoundary keeps the tree inside the text block rather than
// letting it run out over the whole canvas.
LimitToTextBoundary bool
// CharLastLinked is the character the most recent Step joined to the
// tree, or nil if that Step joined none.
CharLastLinked *Character
// CharLinkOrder is every character the tree has reached, starting one,
// in the order it reached them. This is the order effects animate in.
CharLinkOrder []*Character
// EdgeChars are the characters still able to grow the tree.
EdgeChars []*Character
// EdgeLastAdded and EdgeLastPopped are the last character put on the edge
// and the last one taken off it.
EdgeLastAdded *Character
EdgeLastPopped *Character
// Complete says the tree has stopped growing. See Step: it turns true one
// Step after the last edge is used up, not on the same one.
Complete bool
// contains filtered or unexported fields
}
PrimsSimple grows a tree by repeatedly picking a random character off the edge of what it has already built and linking it to a random unlinked neighbour. The result wanders: it is what burn uses to spread a fire.
func NewPrimsSimple ¶ added in v0.3.0
func NewPrimsSimple(e *Engine, startingChar *Character, limitToTextBoundary bool) (*PrimsSimple, error)
NewPrimsSimple starts a tree. A nil startingChar picks a random coordinate on the canvas, which needs fill characters to be reliable.
func (*PrimsSimple) Step ¶ added in v0.3.0
func (p *PrimsSimple) Step(e *Engine)
Step grows the tree by at most one edge.
Complete turns true on the Step that finds the edge already empty, not on the Step that empties it. That is upstream's behaviour and it costs one extra frame; an effect that loops until Complete gets one Step where nothing happens. Do not tighten it: the frame count of every effect built on this is tuned to it.
type PrimsWeighted ¶ added in v0.3.0
type PrimsWeighted struct {
// LimitToTextBoundary keeps the tree inside the text block.
LimitToTextBoundary bool
// CharLastLinked is the character the most recent Step joined, or nil
// once the tree is finished.
CharLastLinked *Character
// CharLinkOrder is every character the tree has reached, in order.
CharLinkOrder []*Character
// NeighborsLastAdded are the characters the most recent Step offered up
// as new candidates.
NeighborsLastAdded []*Character
// Complete says the tree has stopped growing.
Complete bool
// contains filtered or unexported fields
}
PrimsWeighted gives every character a random weight once, then always grows towards the cheapest character on the frontier. The tree it builds looks less like a random walk and more like something seeping outwards, which is why smoke uses it.
func NewPrimsWeighted ¶ added in v0.3.0
func NewPrimsWeighted(e *Engine, startingChar *Character, limitToTextBoundary bool) (*PrimsWeighted, error)
NewPrimsWeighted starts a tree. A nil startingChar picks a random coordinate.
func (*PrimsWeighted) Step ¶ added in v0.3.0
func (p *PrimsWeighted) Step(e *Engine)
Step grows the tree by one edge, taking the cheapest one available.
type Print ¶ added in v0.4.0
type Print struct {
// contains filtered or unexported fields
}
Print types the canvas out one line at a time on the bottom row, lifting the finished lines above it as it goes, so the text arrives the way a teletype would deliver it. Between lines a block runs back along the bottom row to the column the next line starts in.
This effect assembles the screen rather than passing over it, so every character stays hidden until the head strikes it. That holds under every colour policy, including DynamicExistingColors: showing the picture up front would leave the head nothing to type.
func NewPrint ¶ added in v0.4.0
func NewPrint(config PrintConfig) *Print
NewPrint builds the effect.
type PrintConfig ¶ added in v0.4.0
type PrintConfig struct {
// PrintHeadReturnSpeed is how fast the head travels back to the start of
// the next line. Raise it to shorten the pause between lines.
PrintHeadReturnSpeed float64
// PrintSpeed is how many characters are typed per frame.
PrintSpeed int
// PrintHeadEasing shapes the head's travel during a carriage return.
PrintHeadEasing Easing
// FinalGradientStops colour the typed text. They are ignored when the
// engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
PrintConfig tunes the print effect.
func DefaultPrintConfig ¶ added in v0.4.0
func DefaultPrintConfig() PrintConfig
DefaultPrintConfig is upstream's default print.
type Rain ¶
type Rain struct {
// contains filtered or unexported fields
}
Rain drops every character in from the top of the canvas, one row at a time from the bottom up, and fades it to its final colour when it lands.
type RainConfig ¶
type RainConfig struct {
// RainColors are picked at random per drop.
RainColors []Color
// MovementSpeedLow and MovementSpeedHigh bound each drop's fall speed.
MovementSpeedLow float64
MovementSpeedHigh float64
// RainSymbols are the glyphs a drop can wear on the way down.
RainSymbols []string
// FinalGradientStops colour the text once it lands. They are ignored when
// the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
// MovementEasing shapes the fall. The default accelerates downward.
MovementEasing Easing
}
RainConfig tunes the rain effect.
func DefaultRainConfig ¶
func DefaultRainConfig() RainConfig
DefaultRainConfig is upstream's default rain.
type RandomSequence ¶ added in v0.4.0
type RandomSequence struct {
// contains filtered or unexported fields
}
RandomSequence hides the whole text, then fades characters back in one at a time in a random order. Nothing moves and nothing waits on anything else: each character runs its own short ramp from the terminal background to its final colour as soon as its turn comes up.
func NewRandomSequence ¶ added in v0.4.0
func NewRandomSequence(config RandomSequenceConfig) *RandomSequence
NewRandomSequence builds the effect.
func (*RandomSequence) Advance ¶ added in v0.4.0
func (r *RandomSequence) Advance(e *Engine) bool
Advance releases the next few characters and reports whether the effect is still going.
func (*RandomSequence) Build ¶ added in v0.4.0
func (r *RandomSequence) Build(e *Engine) error
Build hides every character, gives it a fade-in scene, and shuffles the order they will be released in.
type RandomSequenceConfig ¶ added in v0.4.0
type RandomSequenceConfig struct {
// Speed is the share of the text revealed per frame, so 0.007 reveals
// seven characters per thousand. It is turned into a whole number of
// characters once, at build time, and never drops below one.
Speed float64
// FinalGradientStops colour the text as it fades in. They are ignored
// when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
// FinalGradientFrames is how many frames each step of a character's
// fade-in holds. Raise it to make each character arrive more slowly.
FinalGradientFrames int
FinalGradientDirection GradientDirection
}
RandomSequenceConfig tunes the randomsequence effect.
func DefaultRandomSequenceConfig ¶ added in v0.4.0
func DefaultRandomSequenceConfig() RandomSequenceConfig
DefaultRandomSequenceConfig is upstream's default randomsequence.
type RecursiveBacktracker ¶ added in v0.3.0
type RecursiveBacktracker struct {
// LimitToTextBoundary keeps the walk inside the text block.
LimitToTextBoundary bool
// CharLastLinked is the character this Step joined, or nil if this Step
// backtracked instead of moving forward.
CharLastLinked *Character
// CharLinkOrder is every character reached, in order.
CharLinkOrder []*Character
// Stack is the route back to the last character with an unvisited
// neighbour.
Stack []*Character
// StackLastPopped is the character this Step backtracked off the stack,
// or nil if this Step moved forward instead.
StackLastPopped *Character
// Complete says the walk has stopped.
Complete bool
// contains filtered or unexported fields
}
RecursiveBacktracker walks as far as it can in one direction, then backs up to the last character with somewhere left to go. The tree it makes is long corridors rather than a spreading blob, which is what laseretch cuts along.
func NewRecursiveBacktracker ¶ added in v0.3.0
func NewRecursiveBacktracker(e *Engine, startingChar *Character, limitToTextBoundary bool) (*RecursiveBacktracker, error)
NewRecursiveBacktracker starts a walk. A nil startingChar picks a random coordinate.
func (*RecursiveBacktracker) Step ¶ added in v0.3.0
func (r *RecursiveBacktracker) Step(e *Engine)
Step either moves forward into an unvisited neighbour or backs up one. Exactly one of CharLastLinked and StackLastPopped is set afterwards, and both are cleared first, so an effect can tell which of the two happened.
type Rings ¶ added in v0.4.0
type Rings struct {
// contains filtered or unexported fields
}
Rings gathers the text into concentric spinning rings, scatters it, spins it again, and finally walks every character home.
This effect neither passes over the screen nor assembles it: it starts from the assembled picture and takes it apart. Upstream already shows every character in place, in its final colour, on the first frame, because the rings have to form out of text the viewer has seen. That is exactly what DynamicExistingColors needs, so nothing here is scoped to the colour policy beyond the colours themselves.
func NewRings ¶ added in v0.4.0
func NewRings(config RingsConfig) *Rings
NewRings builds the effect.
type RingsConfig ¶ added in v0.4.0
type RingsConfig struct {
// RingColors are cycled through as the rings are built, so ring 0 takes
// the first colour, ring 1 the second, and so on.
RingColors []Color
// RingGap is the distance between rings, as a share of the smaller canvas
// dimension. It is also how far a character wanders while dispersed.
RingGap float64
// SpinDuration is how many frames each spinning stretch lasts.
SpinDuration int
// SpinSpeedLow and SpinSpeedHigh bound a ring's rotation speed. Each ring
// draws its own speed from the range, which is what stops the rings
// turning as one disc.
SpinSpeedLow float64
SpinSpeedHigh float64
// DisperseDuration is how many frames the characters spend scattered
// between spinning stretches.
DisperseDuration int
// SpinDisperseCycles is how many times the effect spins and scatters
// before the text goes home.
SpinDisperseCycles int
// FinalGradientStops colour the text once it settles. They are ignored
// when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
RingsConfig tunes the rings effect.
func DefaultRingsConfig ¶ added in v0.4.0
func DefaultRingsConfig() RingsConfig
DefaultRingsConfig is upstream's default rings.
type Rng ¶
type Rng struct {
// contains filtered or unexported fields
}
Rng is the engine's source of randomness.
ttfx clones Python's Mersenne Twister so that it can reproduce upstream frame for frame. This port makes no parity claim, so it uses Go's own generator. Seeding it makes a run reproducible, which is what the tests need; nothing here will match either of the other two implementations.
func (*Rng) IndexBelow ¶
IndexBelow returns an index in [0, n). It exists so the generic helpers below can stay free functions: Go does not allow a generic method.
func (*Rng) IntBetween ¶
IntBetween returns an integer in [low, high]. Both ends are included, which is what upstream's randint does. A reversed range returns low.
type Scattered ¶ added in v0.4.0
type Scattered struct {
// contains filtered or unexported fields
}
Scattered drops every character at a random spot on the canvas, holds that still for a moment, then walks each one to where it belongs.
This effect ASSEMBLES the screen rather than passing over it, so it does not show the picture in place on the first frame. Upstream already makes every character visible during the build, because a character has to be seen at its scattered start for the gathering to read at all. Under DynamicExistingColors that is the right behaviour unchanged: the screen starts as the same picture shuffled, and reassembles into itself.
func NewScattered ¶ added in v0.4.0
func NewScattered(config ScatteredConfig) *Scattered
NewScattered builds the effect.
type ScatteredConfig ¶ added in v0.4.0
type ScatteredConfig struct {
// MovementSpeed is how fast a character travels to where it belongs.
MovementSpeed float64
// MovementEasing shapes that travel. The default overshoots at both ends,
// which is what makes the gathering read as a snap rather than a drift.
MovementEasing Easing
// FinalGradientStops colour the text once it is in place. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
// FinalGradientFrames is how many frames each colour step holds.
FinalGradientFrames int
}
ScatteredConfig tunes the scattered effect.
func DefaultScatteredConfig ¶ added in v0.4.0
func DefaultScatteredConfig() ScatteredConfig
DefaultScatteredConfig is upstream's default scattered.
type Scene ¶
type Scene struct {
ID string
IsLooping bool
Sync SyncMetric
Ease Easing
HasEase bool
// contains filtered or unexported fields
}
Scene is a named sequence of frames on one character.
type SceneOptions ¶
type SceneOptions struct {
Looping bool
Sync SyncMetric
Ease Easing
HasEase bool
UsesInputColors bool
// Frames is how many frames the caller is about to add, if it knows.
// Nothing depends on it being right, but a scene with eighty frames
// regrows its slices seven times without it, and over a full screen that
// regrowth is most of what the build allocates.
Frames int
}
SceneOptions are the knobs NewScene accepts.
type Segment ¶
type Segment struct {
Start Waypoint
End Waypoint
Distance float64
// contains filtered or unexported fields
}
Segment is the span between two waypoints, with the flags that stop its enter and exit events firing twice.
type Slice ¶ added in v0.4.0
type Slice struct {
// contains filtered or unexported fields
}
Slice cuts the picture in two, throws each half off the canvas by a different edge, and slides both back at once. Every character is placed and released in Build, so Advance only has to run frames until the movement stops.
This effect assembles the screen rather than passing over it: nothing stands on its own coordinate when the first frame is drawn. That holds under every colour policy, DynamicExistingColors included. Revealing the whole picture up front, which is what a sweep like waves has to do, would leave the slice with nothing to bring in.
func NewSlice ¶ added in v0.4.0
func NewSlice(config SliceConfig) *Slice
NewSlice builds the effect.
type SliceConfig ¶ added in v0.4.0
type SliceConfig struct {
// Direction is the axis the cut runs along.
Direction SliceDirection
// MovementSpeed is how fast a character travels back to its place. The
// horizontal cut doubles it, because it crosses the width of the canvas
// rather than its height.
MovementSpeed float64
// MovementEasing shapes the travel. The default holds the halves still,
// throws them across, and settles them, which is what makes the two sides
// read as one cut rather than two slides.
MovementEasing Easing
// FinalGradientStops colour the text once it lands. They are ignored when
// the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
SliceConfig tunes the slice effect.
func DefaultSliceConfig ¶ added in v0.4.0
func DefaultSliceConfig() SliceConfig
DefaultSliceConfig is upstream's default slice.
type SliceDirection ¶ added in v0.4.0
type SliceDirection int
SliceDirection is the axis the cut runs along.
const ( // SliceVertical cuts down the middle column. The left half falls in from // above and the right half rises in from below. SliceVertical SliceDirection = iota // SliceHorizontal cuts across the middle row. The bottom half comes in // from the left and the top half from the right. SliceHorizontal // SliceDiagonal cuts along the diagonals. Half the diagonals rise from // below and half fall from above. SliceDiagonal )
The three directions upstream offers.
func ParseSliceDirection ¶ added in v0.4.0
func ParseSliceDirection(name string) (SliceDirection, bool)
ParseSliceDirection looks a direction up by its upstream name.
type Slide ¶ added in v0.4.0
type Slide struct {
// contains filtered or unexported fields
}
Slide parks every character just off the edge of the canvas and pushes the groups on one at a time, each group feeding its characters in one per frame.
This effect assembles the screen rather than passing over it, so a character stays hidden until its turn comes. That holds under every colour policy, DynamicExistingColors included: revealing the whole picture up front would leave nothing for the slide to bring in.
func NewSlide ¶ added in v0.4.0
func NewSlide(config SlideConfig) *Slide
NewSlide builds the effect.
type SlideConfig ¶ added in v0.4.0
type SlideConfig struct {
// MovementSpeed is how fast a character travels to its place. Raise it to
// make the slide snappier.
MovementSpeed float64
// Grouping is the axis the characters travel along.
Grouping SlideGrouping
// Gap is how many frames to wait before releasing the next group.
Gap int
// ReverseDirection sends the groups in from the other side. It is ignored
// when Merge is set, because Merge already uses both sides.
ReverseDirection bool
// Merge sends every other group in from the opposite side, so the groups
// meet in the middle.
Merge bool
// MovementEasing shapes the travel. The default eases in and out, which is
// what makes a group look like it is being pushed rather than dropped.
MovementEasing Easing
// FinalGradientStops colour the text once it lands. They are ignored when
// the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
// FinalGradientFrames is how many frames each step of a character's
// colour ramp holds.
FinalGradientFrames int
}
SlideConfig tunes the slide effect.
func DefaultSlideConfig ¶ added in v0.4.0
func DefaultSlideConfig() SlideConfig
DefaultSlideConfig is upstream's default slide.
type SlideGrouping ¶ added in v0.4.0
type SlideGrouping int
SlideGrouping is the axis the characters travel along.
const ( // SlideByRow slides each row in sideways. SlideByRow SlideGrouping = iota // SlideByColumn slides each column in vertically. SlideByColumn // SlideByDiagonal slides each diagonal in along itself. SlideByDiagonal )
The three groupings upstream offers.
func ParseSlideGrouping ¶ added in v0.4.0
func ParseSlideGrouping(name string) (SlideGrouping, bool)
ParseSlideGrouping looks a grouping up by its upstream name.
type Smoke ¶ added in v0.4.0
type Smoke struct {
// contains filtered or unexported fields
}
Smoke lights one cell of the canvas and lets the smoke seep outwards from it. Every character sits dull until the smoke arrives, plays a run of block symbols while it drifts through, and is left wearing its final colour.
The order the smoke spreads in is a weighted spanning tree: every character is given a random cost once, the tree always grows towards the cheapest cell on its frontier, and a breadth-first walk of the finished tree is what the effect animates, one layer per frame. That is why the smoke wanders and pools rather than expanding as a clean ring.
This effect passes over the screen rather than assembling it, so every character is visible from the first frame. That is upstream's own behaviour: smoke never hides anything, it only changes what a character is wearing.
func NewSmoke ¶ added in v0.4.0
func NewSmoke(config SmokeConfig) *Smoke
NewSmoke builds the effect.
type SmokeConfig ¶ added in v0.4.0
type SmokeConfig struct {
// StartingColor is what the text wears before the smoke reaches it. It is
// ignored when the engine resolves to the input's own colours, except for
// a character that arrived carrying none.
StartingColor Color
// SmokeSymbols are played in order as the smoke passes over a character.
SmokeSymbols []string
// SmokeGradientStops colour the smoke itself. They run into the final
// gradient's stops, reversed, so the smoke thins out into the colour the
// text is about to take.
SmokeGradientStops []Color
// UseWholeCanvas lets the smoke out of the text block and over the whole
// canvas.
UseWholeCanvas bool
// FinalGradientStops colour the text once the smoke has passed. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
SmokeConfig tunes the smoke effect.
func DefaultSmokeConfig ¶ added in v0.4.0
func DefaultSmokeConfig() SmokeConfig
DefaultSmokeConfig is upstream's default smoke.
type Spotlights ¶ added in v0.4.0
type Spotlights struct {
// contains filtered or unexported fields
}
Spotlights sweeps beams of light over a darkened screen. Nothing moves and nothing is hidden: every character is on screen from the first frame wearing a dimmed version of the colour it will end on, and a beam passing over it brings it up to full brightness and drops it back again.
It is an effect that passes over the screen rather than one that assembles it, so under DynamicExistingColors the whole picture, backgrounds included, is there from frame one. Upstream already builds it that way.
The beams themselves are characters the effect adds to the terminal and never makes visible. They exist to carry a path, and their coordinate is what the illumination is measured from.
func NewSpotlights ¶ added in v0.4.0
func NewSpotlights(config SpotlightsConfig) *Spotlights
NewSpotlights builds the effect.
func (*Spotlights) Advance ¶ added in v0.4.0
func (s *Spotlights) Advance(e *Engine) bool
Advance lights the characters under the beams, then moves the beams on.
func (*Spotlights) Build ¶ added in v0.4.0
func (s *Spotlights) Build(e *Engine) error
Build works out the lit and unlit colour of every character, shows the whole screen in its unlit colour, and sends the beams off on their wander.
type SpotlightsConfig ¶ added in v0.4.0
type SpotlightsConfig struct {
// BeamWidthRatio sets how wide a beam is. The beam reaches the smaller of
// the canvas dimensions divided by this number, so a larger value gives a
// narrower beam. It must be above zero.
BeamWidthRatio float64
// BeamFalloff is how much of the beam's width is soft edge, as a fraction
// of the whole. At 0.3 the outer three tenths fade off, and a character
// right on the rim shows at a fifth of its brightness. Zero gives a hard
// edged beam.
BeamFalloff float64
// SearchDuration is how many frames the beams wander for before they head
// for the middle of the canvas.
SearchDuration int
// SearchSpeedMin and SearchSpeedMax bound the speed of each leg of a
// beam's wandering. Every leg picks its own speed from this range, which
// is what stops several beams moving in step.
//
// ttfx carries this as one range argument. Two fields read better in Go
// and hold the same two numbers.
SearchSpeedMin float64
SearchSpeedMax float64
// SpotlightCount is how many beams search. They all converge on the same
// point, and only the first of them stays on to do the widening.
SpotlightCount int
// FinalGradientStops colour the text the beams travel over. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
SpotlightsConfig tunes the spotlights effect.
func DefaultSpotlightsConfig ¶ added in v0.4.0
func DefaultSpotlightsConfig() SpotlightsConfig
DefaultSpotlightsConfig is upstream's default spotlights.
type Spray ¶ added in v0.4.0
type Spray struct {
// contains filtered or unexported fields
}
Spray fires every character out of a single point and lets it fly to where it belongs. Nothing is on the screen until the nozzle reaches it, so the text assembles rather than being swept over.
func NewSpray ¶ added in v0.4.0
func NewSpray(config SprayConfig) *Spray
NewSpray builds the effect.
type SprayConfig ¶ added in v0.4.0
type SprayConfig struct {
// SprayPosition is where on the canvas the characters are fired from.
SprayPosition SprayPosition
// SprayVolume is how many characters leave the nozzle each frame, as a
// fraction of the total. It is a ceiling: each frame fires somewhere
// between one character and that many.
SprayVolume float64
// MovementSpeedLow and MovementSpeedHigh bound each character's flight
// speed.
MovementSpeedLow float64
MovementSpeedHigh float64
// MovementEasing shapes the flight. The default leaves the nozzle fast
// and drifts into place.
MovementEasing Easing
// FinalGradientStops colour the text once it lands. They are ignored when
// the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
SprayConfig tunes the spray effect.
func DefaultSprayConfig ¶ added in v0.4.0
func DefaultSprayConfig() SprayConfig
DefaultSprayConfig is upstream's default spray.
type SprayPosition ¶ added in v0.4.0
type SprayPosition int
SprayPosition is the point on the canvas every character is fired from.
const ( SprayEast SprayPosition = iota SprayNorth SprayNorthEast SpraySouth SpraySouthEast SprayWest SprayNorthWest SpraySouthWest SprayCenter )
The nine spray origins. They name a compass point on the canvas edge, plus the middle. East is first so the zero value is upstream's default.
func ParseSprayPosition ¶ added in v0.4.0
func ParseSprayPosition(name string) (SprayPosition, bool)
ParseSprayPosition looks up a spray origin by its upstream name.
type Swarm ¶ added in v0.4.0
type Swarm struct {
// contains filtered or unexported fields
}
Swarm splits the text into groups, launches one group at a time from a point off the canvas, and flies each group between a few gathering areas before its members break away to their own cells.
This effect assembles the screen rather than passing over it, so under DynamicExistingColors it still starts from an empty canvas: a character becomes visible only when its swarm launches. Showing every character from the first frame, which is what a sweeping effect has to do, would leave the finished picture on screen with the swarms crawling over the top of it.
func NewSwarm ¶ added in v0.4.0
func NewSwarm(config SwarmConfig) *Swarm
NewSwarm builds the effect.
type SwarmConfig ¶ added in v0.4.0
type SwarmConfig struct {
// BaseColors are the swarm body colours. Each swarm picks one.
BaseColors []Color
// FlashColor is what a character wears at the top of every flight.
FlashColor Color
// SwarmSize is the share of all characters in one swarm, from 0 to 1.
SwarmSize float64
// SwarmCoordination is the chance that a character follows the first of
// its swarm to reach the next gathering area, from 0 to 1.
SwarmCoordination float64
// SwarmAreaCountLow and SwarmAreaCountHigh bound how many gathering areas
// a swarm visits.
SwarmAreaCountLow int
SwarmAreaCountHigh int
// FinalGradientStops colour the text once it lands. They are ignored when
// the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
SwarmConfig tunes the swarm effect.
func DefaultSwarmConfig ¶ added in v0.4.0
func DefaultSwarmConfig() SwarmConfig
DefaultSwarmConfig is upstream's default swarm.
type Sweep ¶ added in v0.4.0
type Sweep struct {
// contains filtered or unexported fields
}
Sweep runs two bands across the canvas. The first uncovers every cell in grey, the second passes back the other way and leaves each cell in its final colour. Nothing moves: a cell wears the band for a moment as it goes by.
This effect assembles the screen rather than passing over it. The first band is the reveal: every character starts hidden and is only shown when the band reaches it. So under DynamicExistingColors the characters stay hidden at build time, unlike waves, which passes over a picture that is already there.
func NewSweep ¶ added in v0.4.0
func NewSweep(config SweepConfig) *Sweep
NewSweep builds the effect.
type SweepConfig ¶ added in v0.4.0
type SweepConfig struct {
// SweepSymbols are the glyphs a cell cycles through while a band is on it.
// The default fades from a solid block down to a light one, which is what
// makes the band read as a shimmer rather than a wipe.
SweepSymbols []string
// FirstSweepDirection is the axis the first band travels along. That band
// uncovers the characters in grey.
FirstSweepDirection CharacterGroup
// SecondSweepDirection is the axis the second band travels along. That
// band colours the characters.
SecondSweepDirection CharacterGroup
// FinalGradientStops colour the text once both bands have passed. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
SweepConfig tunes the sweep effect.
func DefaultSweepConfig ¶ added in v0.4.0
func DefaultSweepConfig() SweepConfig
DefaultSweepConfig is upstream's default sweep.
type SyncMetric ¶
type SyncMetric int
SyncMetric ties an animation to the progress of the character's motion.
const ( SyncNone SyncMetric = iota SyncDistance SyncStep )
The two sync metrics, plus the absence of one.
type SynthGrid ¶ added in v0.4.0
type SynthGrid struct {
// contains filtered or unexported fields
}
SynthGrid draws a grid over the canvas, then fills the blocks it made a few at a time, then takes the grid back down.
It assembles the screen rather than passing over it: every character starts hidden and is shown when its block's turn comes. So under DynamicExistingColors it keeps upstream's hiding, unlike a sweep such as waves, which has to show the picture from the first frame. Showing everything up front here would leave nothing for the blocks to fill in.
func NewSynthGrid ¶ added in v0.4.0
func NewSynthGrid(config SynthGridConfig) *SynthGrid
NewSynthGrid builds the effect.
type SynthGridConfig ¶ added in v0.4.0
type SynthGridConfig struct {
// GridGradientStops and GridGradientSteps colour the grid lines, painted
// across the whole canvas rather than across the text.
GridGradientStops []Color
GridGradientSteps []int
// GridGradientDirection is the axis the grid colour runs along.
GridGradientDirection GradientDirection
// TextGradientStops and TextGradientSteps colour the text once it
// resolves. They are ignored when the engine is set to resolve to the
// input's own colours.
TextGradientStops []Color
TextGradientSteps []int
// TextGradientDirection is the axis the text colour runs along.
TextGradientDirection GradientDirection
// GridRowSymbol and GridColumnSymbol draw the horizontal and vertical
// grid lines.
GridRowSymbol string
GridColumnSymbol string
// TextGenerationSymbols are the glyphs a cell flickers through before it
// settles into its own character.
TextGenerationSymbols []string
// MaxActiveBlocks is the share of the grid's blocks allowed to be filling
// in at once. At 0.1 a tenth of the screen is working at any moment, so
// the fill reads as a sweep rather than as one flash.
MaxActiveBlocks float64
}
SynthGridConfig tunes the synthgrid effect.
func DefaultSynthGridConfig ¶ added in v0.4.0
func DefaultSynthGridConfig() SynthGridConfig
DefaultSynthGridConfig is upstream's default synthgrid.
type Terminal ¶
type Terminal struct {
Config TerminalConfig
Canvas *Canvas
// Characters is every character, in allocation order.
Characters []*Character
InputCharacters []*Character
InnerFillCharacters []*Character
OuterFillCharacters []*Character
AddedCharacters []*Character
// contains filtered or unexported fields
}
Terminal owns every character and paints the frame.
func NewTerminalFromCells ¶
func NewTerminalFromCells(grid [][]InputCell, cfg TerminalConfig) *Terminal
NewTerminalFromCells builds a terminal from a captured cell grid. Row zero of the grid is the top of the screen, matching how screen captures are stored; the canvas flips it so row 1 is the bottom.
A cell's own colours become the character's input colours, so an effect run with DynamicExistingColors resolves the screen back to how it looked.
func NewTerminalFromText ¶
func NewTerminalFromText(input string, cfg TerminalConfig) *Terminal
NewTerminalFromText builds a terminal from plain text. Tabs expand, trailing blank space is dropped, and each remaining rune becomes a character.
func (*Terminal) AddCharacter ¶
AddCharacter creates a character that was not in the input. It joins the added population only, so ordinary queries do not see it.
func (*Terminal) CharacterAtInputCoord ¶
CharacterAtInputCoord finds the character that started at a coordinate.
func (*Terminal) CollectCharacters ¶
func (t *Terminal) CollectCharacters(filter CharacterFilter) []*Character
CollectCharacters returns the selected populations in allocation order.
func (*Terminal) Frame ¶
Frame returns the current frame as an ANSI string, top row first, with rows separated by newlines and no trailing newline.
func (*Terminal) FrameRows ¶
func (t *Terminal) FrameRows() [][]*CharacterVisual
FrameRows returns the current frame as rows of visuals, top row first. A nil entry is an empty cell. The slices are reused between calls, so a caller that keeps them must copy.
func (*Terminal) GetCharacters ¶
func (t *Terminal) GetCharacters(rng *Rng, filter CharacterFilter, order CharacterSort) []*Character
GetCharacters returns the selected populations in the requested order.
func (*Terminal) GetCharactersGrouped ¶
func (t *Terminal) GetCharactersGrouped(filter CharacterFilter, grouping CharacterGroup) [][]*Character
GetCharactersGrouped buckets the selected populations into ordered groups.
func (*Terminal) Neighbors ¶ added in v0.3.0
Neighbors returns the characters directly north, east, south and west of a character, in that order, skipping any of the four cells that holds none. Diagonals are not neighbours.
Upstream snapshots these four slots onto every character when the terminal is built. This looks them up on demand instead. The two are equivalent: the snapshot is taken from the same input-coordinate table this reads, and the table never changes afterwards because AddCharacter deliberately stays out of it. Looking them up saves four pointers per character over a full screen.
A character created with AddCharacter has no neighbours, because it has no entry in the table. That matches upstream.
func (*Terminal) SetCharacterVisibility ¶
SetCharacterVisibility shows or hides a character.
type TerminalConfig ¶
type TerminalConfig struct {
// Width and Height are the canvas size in cells. Both must be above zero.
Width int
Height int
// TabWidth is how many columns a tab expands to. Zero means four.
TabWidth int
// ExistingColorHandling decides what happens to colours the input carried.
ExistingColorHandling ExistingColorHandling
// AnchorText pins the input block inside the canvas.
AnchorText Anchor
// MakeFillCharacters populates every empty canvas cell with a space
// character that effects can animate. Effects that only touch input
// characters do not need it, and it costs one character per empty cell.
MakeFillCharacters bool
}
TerminalConfig sets up the canvas an effect draws on.
type Thunderstorm ¶ added in v0.4.0
type Thunderstorm struct {
// contains filtered or unexported fields
}
Thunderstorm dims the text, rains on it, and strikes it with lightning.
The text is on screen the whole time: it fades down to a dim version of itself, weather happens over the top of it, and it fades back up at the end. A strike is drawn as a column of added characters that walks down from the top of the canvas one small batch a frame, forking now and then. When it lands, every character on the screen flashes, the cells the strike passed through are left glowing, and a handful of sparks fly out of the point of impact and cool as they go.
This effect passes over the screen rather than assembling it. Every character is visible and wearing the colour it will settle back to from the first frame, in every colour mode, because there is nothing here that reveals the text: the storm plays over a picture that is already there. So there is no reveal to defer and no waves-style pre-show to add under DynamicExistingColors, and upstream needs no deviation for it. Backgrounds need none either: ttfx already carries the input background through the dim, the flash and the glow, so a selection bar or a filled panel on a captured screen dims and brightens with everything else instead of blinking out.
func NewThunderstorm ¶ added in v0.4.0
func NewThunderstorm(config ThunderstormConfig) *Thunderstorm
NewThunderstorm builds the effect.
func (*Thunderstorm) Advance ¶ added in v0.4.0
func (t *Thunderstorm) Advance(e *Engine) bool
Advance runs one frame.
func (*Thunderstorm) Build ¶ added in v0.4.0
func (t *Thunderstorm) Build(e *Engine) error
Build stocks the two particle pools and the strike characters, then gives every input character the four scenes it needs: the dim it starts with, the brighten it ends with, the flash a strike sets off and the glow a strike leaves behind.
type ThunderstormConfig ¶ added in v0.4.0
type ThunderstormConfig struct {
// LightningColor is what a strike is drawn in.
LightningColor Color
// GlowingTextColor is the colour a character is left glowing after a
// strike has passed through its cell.
GlowingTextColor Color
// TextGlowTime is how long each colour of that glow is held. Raise it to
// cool the text more slowly.
TextGlowTime int
// RaindropSymbols are what a raindrop can look like.
RaindropSymbols []string
// SparkSymbols are what a spark thrown off by an impact can look like.
SparkSymbols []string
// SparkGlowColor is the colour a spark starts at before it cools.
SparkGlowColor Color
// SparkGlowTime is how long each colour of a spark's cooling is held.
SparkGlowTime int
// StormTime is how long the storm lasts, in seconds. The engine's clock
// counts frames rather than the machine, so this is seconds of animation
// at the rate the host says it paints at; see clock.go.
StormTime int
// FinalGradientStops colour the text once the sky has cleared. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
// FinalGradientFrames is carried for parity with upstream's options and
// changes nothing. Upstream declares it and never reads it: thunderstorm
// has no separate final-gradient scene, because the text is already
// wearing its final colour before the storm starts and only dims away
// from it and back.
FinalGradientFrames int
}
ThunderstormConfig tunes the thunderstorm effect.
func DefaultThunderstormConfig ¶ added in v0.4.0
func DefaultThunderstormConfig() ThunderstormConfig
DefaultThunderstormConfig is upstream's default thunderstorm.
type TuffBaby ¶ added in v0.5.0
type TuffBaby struct {
// contains filtered or unexported fields
}
TuffBaby gathers the text on screen into a portrait, plays the clip in it, and puts the text back.
The characters that make up the picture are the ones that were already there. When there are more than the picture needs, the surplus flies off the nearest edge and waits there; when there are fewer, the effect appends characters of its own, which fly in from off screen and leave the same way.
The cells are the union of every frame, so a character keeps one cell for the whole run. A frame that does not cover its cell hides it, which is how the silhouette moves without anything moving.
func NewTuffBaby ¶ added in v0.5.0
func NewTuffBaby(config TuffBabyConfig) *TuffBaby
NewTuffBaby builds the effect.
type TuffBabyConfig ¶ added in v0.5.0
type TuffBabyConfig struct {
// GatherEase and GatherSpeed shape the flight from the text into the
// picture. HomeEase and HomeSpeed shape the flight back.
GatherEase Easing
GatherSpeed float64
HomeEase Easing
HomeSpeed float64
// ExitEase and ExitSpeed shape the surplus's flight off the screen.
//
// The surplus is not part of the picture and on a wide screen there is
// more of it than there is picture: 240 columns of text hands the picture
// about five thousand characters and leaves about six thousand over.
// Flown at the gather's speed and curve, that surplus takes three
// quarters of a second to clear, and it does not clear evenly. The
// gather eases out, so a character covers most of its distance at once
// and then creeps the last of the way; applied to a flight whose target
// is an edge, that puts every surplus character near an edge early and
// leaves it there. The left and right of the screen carry a readable
// band of text for the whole of that time, while the picture in the
// middle is still nothing anyone can recognise. The wider the terminal
// the further the far characters have to come and the longer the band
// lasts, which is why it reads as debris rather than as motion.
//
// So the surplus leaves at its own speed and, by default, without the
// gather's easing. The surplus is draining off the edges of the screen
// and a drain wants an even flux: at a constant rate nothing queues up
// at the door, and the band that forms is both thinner than the gather's
// and gone in a third of the time. The step per frame stays what the
// gather's own opening frames are, so it still reads as flight.
//
// It also flies the straight line rather than the gather's arc. The arc
// turns a character into the picture, which is what a character joining
// the picture is doing; a character leaving is only getting out of the
// way, and an arc there is a detour across the thing the reader is
// trying to watch form.
//
// A speed of zero or less falls back to GatherSpeed, GatherEase and the
// arc, so a config built by hand before these fields existed behaves
// exactly as it did.
ExitEase Easing
ExitSpeed float64
// PoseFrames is how long the first frame of the clip is held before it
// starts playing, so a reader gets to see what the picture is.
PoseFrames int
// Loops is how many times the clip plays.
Loops int
// SourceFrameRate is how many of the clip's frames play per second of
// engine time. The source runs at ten, so ten plays it at its own speed.
//
// It is read against Engine.Clock rather than against a count of host
// frames, so the clip lasts the same number of seconds whether the host
// paints sixty frames a second or two hundred and forty. A host that
// leaves the engine's clock at a rate it does not paint at gets the clip
// at the wrong speed, which is the clock's contract, not this field's.
SourceFrameRate float64
// FillerSymbols are the symbols appended characters wear when the screen
// carries no text of its own to recycle.
FillerSymbols []string
// Tones colour the picture, darkest first. There must be exactly
// tuffToneCount of them, matching the levels the reference was reduced to.
//
// The defaults are not the source's own greys. The source is a light
// picture on a white ground and a terminal is the other way up: the
// darkest band painted as the near-black it really is takes the whole
// shadowed side of the face out. The ramp keeps the source's tonal order
// and lifts its dark end until every band reads against a dark terminal.
Tones []Color
// FinalGradientStops colour the text once it is home again. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
TuffBabyConfig tunes the tuffbaby effect.
func DefaultTuffBabyConfig ¶ added in v0.5.0
func DefaultTuffBabyConfig() TuffBabyConfig
DefaultTuffBabyConfig is the effect as it is meant to be seen.
type Unstable ¶ added in v0.4.0
type Unstable struct {
// contains filtered or unexported fields
}
Unstable scatters the characters into each other's places, shakes the whole screen while it heats up, throws every character off the nearest edge, and then flies them all back where they belong.
It reassembles rather than sweeps, but nothing is hidden at any point: the characters are all on screen from the first frame, standing in the wrong places. That is upstream's own behaviour, so DynamicExistingColors needs no deviation for it here.
func NewUnstable ¶ added in v0.4.0
func NewUnstable(config UnstableConfig) *Unstable
NewUnstable builds the effect.
func (*Unstable) Advance ¶ added in v0.4.0
Advance runs one frame and reports whether the effect is still going.
It steps the characters itself rather than calling Engine.Update, as ttfx does: the rumble advances animation without motion, and both flights decide what stays active by where a character has got to rather than by whether it still has work. The clock therefore does not move during this effect, which is also ttfx's behaviour and costs nothing, since unstable never reads it.
type UnstableConfig ¶ added in v0.4.0
type UnstableConfig struct {
// UnstableColor is the colour a character heats up to while it rumbles.
UnstableColor Color
// ExplosionEase and ExplosionSpeed shape the flight out to the canvas edge.
ExplosionEase Easing
ExplosionSpeed float64
// ReassemblyEase and ReassemblySpeed shape the flight back home.
ReassemblyEase Easing
ReassemblySpeed float64
// FinalGradientStops colour the text once it lands. They are ignored when
// the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
UnstableConfig tunes the unstable effect.
func DefaultUnstableConfig ¶ added in v0.4.0
func DefaultUnstableConfig() UnstableConfig
DefaultUnstableConfig is upstream's default unstable.
type VhsTape ¶
type VhsTape struct {
// contains filtered or unexported fields
}
VhsTape plays the screen back off a worn tape: rows slip sideways with colour fringing, a band of tracking noise walks up the picture, the whole thing dissolves into snow, and then it is redrawn row by row.
type VhsTapeConfig ¶
type VhsTapeConfig struct {
// GlitchLineColors are cycled through by a row that slips, which is what
// gives it the colour fringing of a misaligned tape head.
GlitchLineColors []Color
// NoiseColors are the greys the snow is drawn in.
NoiseColors []Color
// GlitchLineChance is the chance per frame that another row slips.
GlitchLineChance float64
// NoiseChance is the chance per frame that the whole picture takes snow.
NoiseChance float64
// TotalGlitchTime is how many frames the glitching lasts before the tape
// gives up and the picture is redrawn.
TotalGlitchTime int
// FinalGradientStops colour the redrawn picture. They are ignored when the
// engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
VhsTapeConfig tunes the vhstape effect.
func DefaultVhsTapeConfig ¶
func DefaultVhsTapeConfig() VhsTapeConfig
DefaultVhsTapeConfig is upstream's default vhstape.
type VisualParams ¶
VisualParams are the settable fields of a CharacterVisual.
type Waves ¶
type Waves struct {
// contains filtered or unexported fields
}
Waves runs a band of rising and falling blocks across the screen. Nothing moves: each character wears the wave for a moment as it passes and is left behind it in its own colour.
type WavesConfig ¶
type WavesConfig struct {
// WaveSymbols are the glyphs a character cycles through as a wave passes
// over it. The default rises and falls, which is what makes it read as a
// wave rather than a flicker.
WaveSymbols []string
// WaveGradientStops and WaveGradientSteps colour the wave itself.
WaveGradientStops []Color
WaveGradientSteps []int
// WaveCount is how many times the wave runs before the characters settle.
WaveCount int
// WaveLength is how many frames each step of the wave holds. Raise it to
// slow the wave down.
WaveLength int
// WaveDirection is the axis the wave travels along.
WaveDirection CharacterGroup
// WaveEasing shapes the wave's travel across each character.
WaveEasing Easing
// FinalGradientStops colour the text once the waves stop. They are ignored
// when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
}
WavesConfig tunes the waves effect.
func DefaultWavesConfig ¶
func DefaultWavesConfig() WavesConfig
DefaultWavesConfig is upstream's default waves.
type Waypoint ¶
Waypoint is a point a Path passes through. Bezier control points bend the approach to it.
type WeightedLink ¶ added in v0.3.0
WeightedLink is one candidate edge and the weight it was drawn with.
type Wipe ¶ added in v0.4.0
type Wipe struct {
// contains filtered or unexported fields
}
Wipe sweeps a line across the screen and shows each character as the line reaches it. Nothing moves and nothing is thrown off: the effect assembles the picture behind the line, so a character is hidden until its turn comes.
type WipeConfig ¶ added in v0.4.0
type WipeConfig struct {
// WipeDirection is the axis the wipe line travels along. The groups it
// names are released one after another, and each group is one line of the
// wipe.
WipeDirection CharacterGroup
// WipeDelay is how many frames to wait between groups. Zero releases one
// group per frame.
WipeDelay int
// WipeEase shapes how fast the line crosses the screen. It is applied to
// the position of the line, not to any one character, so an easing that
// overshoots and comes back takes characters off the screen again on the
// way back.
WipeEase Easing
// FinalGradientStops colour the text once the line has passed. They are
// ignored when the engine is set to resolve to the input's own colours.
FinalGradientStops []Color
FinalGradientSteps []int
FinalGradientDirection GradientDirection
// FinalGradientFrames is how many frames each step of that colour ramp
// holds.
FinalGradientFrames int
}
WipeConfig tunes the wipe effect.
func DefaultWipeConfig ¶ added in v0.4.0
func DefaultWipeConfig() WipeConfig
DefaultWipeConfig is upstream's default wipe.
Source Files
¶
- animation.go
- canvas.go
- character.go
- clock.go
- color.go
- easing.go
- effect.go
- effect_binarypath.go
- effect_blackhole.go
- effect_bouncyballs.go
- effect_bubbles.go
- effect_burn.go
- effect_crumble.go
- effect_decrypt.go
- effect_errorcorrect.go
- effect_expand.go
- effect_fireworks.go
- effect_highlight.go
- effect_laseretch.go
- effect_matrix.go
- effect_middleout.go
- effect_orbittingvolley.go
- effect_overflow.go
- effect_pour.go
- effect_print.go
- effect_rain.go
- effect_randomsequence.go
- effect_rings.go
- effect_scattered.go
- effect_slice.go
- effect_slide.go
- effect_smoke.go
- effect_spotlights.go
- effect_spray.go
- effect_swarm.go
- effect_sweep.go
- effect_synthgrid.go
- effect_thunderstorm.go
- effect_tuffbaby.go
- effect_unstable.go
- effect_vhstape.go
- effect_waves.go
- effect_wipe.go
- engine.go
- events.go
- geometry.go
- motion.go
- ordered.go
- particles.go
- rng.go
- spanning_tree.go
- terminal.go
- tuffbaby_frames.go