anim1d

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 28, 2021 License: Apache-2.0 Imports: 18 Imported by: 2

README

anim1d

PkgGoDev Coverage Status

Stateless 1 dimensional animation code. Designed for:

  • Performance (uses as little floating point operations as possible).
  • Stateless. Can be played forward and backward seamlessly.
  • Serializable.
  • Synchronizable across devices.

Documentation

Overview

Package anim1d draws 1D (line) animations that are stateless.

That is, they can be played forward, backward, on multiple devices synchronized with only clock being synchronized.

It contains all the building blocks to create animations. All the animations are designed to be stateless and serializable so multiple devices can seamless synchronize.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MinMax

func MinMax(v, min, max int) int

MinMax limits the value between a min and a max

func MinMax32

func MinMax32(v, min, max int32) int32

MinMax32 limits the value between a min and a max

Types

type Add

type Add struct {
	Patterns []SPattern // It should be a list of Dim{} with their corresponding weight.
	// contains filtered or unexported fields
}

Add is a generic mixer that merges the output from multiple patterns with saturation.

func (*Add) Render

func (a *Add) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Aurore

type Aurore struct {
}

Aurore is an experimental generator.

It starts slowly, slowly transform itself then disappear.

func (*Aurore) Render

func (a *Aurore) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Bell

type Bell struct{}

Bell is a "good enough" approximation of a gaussian curve by using 2 symmetrical ease-in-out bezier curves.

It is not named Gaussian since it is not a gaussian curve; it really is a bell.

func (*Bell) Scale

func (b *Bell) Scale(v uint16) uint16

Scale scales input [0, 65535] to output [0, 65535] as a bell curve.

type Chronometer

type Chronometer struct {
	Child SPattern
	// contains filtered or unexported fields
}

Chronometer moves 3 lights to the right, each indicating second, minute, and hour passed since the start.

Child has 4 pixels used in this order: [default, second, minute, hour].

func (*Chronometer) Render

func (r *Chronometer) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Color

type Color struct {
	R, G, B uint8
}

Color shows a single color on all lights. It knows how to renders itself into a frame.

If you want a single dot, use a Frame of length one.

func (*Color) Add

func (c *Color) Add(d Color)

Add adds two color together with saturation.

func (*Color) At added in v1.0.1

func (c *Color) At(x, y int) color.Color

At implements image.Image.

func (*Color) Bounds added in v1.0.1

func (c *Color) Bounds() image.Rectangle

Bounds implements image.Image.

func (*Color) ColorModel added in v1.0.1

func (c *Color) ColorModel() color.Model

ColorModel implements image.Image.

func (*Color) Dim

func (c *Color) Dim(intensity uint8)

Dim reduces the intensity of a color/pixel to scale it on intensity.

0 means completely dark, 255 the color c is unaffected.

func (*Color) FromRGBString

func (c *Color) FromRGBString(s string) error

FromRGBString converts a "RRGGBB" encoded string to a Color.

'c' is untouched in case of error.

func (*Color) FromString

func (c *Color) FromString(s string) error

FromString converts a "#RRGGBB" encoded string to a Color.

'c' is untouched in case of error.

func (*Color) MarshalJSON

func (c *Color) MarshalJSON() ([]byte, error)

MarshalJSON encodes the color as a string "#RRGGBB".

func (*Color) Mix

func (c *Color) Mix(d Color, gradient uint8)

Mix blends the second color with the first.

gradient 0 means pure 'c', gradient 255 means pure 'd'.

It is the equivalent of:

c.Dim(255-gradient)
d.Dim(gradient)
c.Add(d)

except that this function doesn't affect d.

func (*Color) Render

func (c *Color) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

func (*Color) String

func (c *Color) String() string

func (*Color) UnmarshalJSON

func (c *Color) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes the string "#RRGGBB" to the color.

If unmarshalling fails, 'c' is not touched.

type Const

type Const int32

Const is a constant value.

func (Const) Eval

func (c Const) Eval(timeMS uint32, l int) int32

Eval implements Value.

func (*Const) MarshalJSON

func (c *Const) MarshalJSON() ([]byte, error)

MarshalJSON encodes the const as a int.

func (*Const) UnmarshalJSON

func (c *Const) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes the int to the const.

If unmarshalling fails, 'c' is not touched.

type Crop

type Crop struct {
	Child  SPattern
	Before SValue // Starting pixels to skip
	After  SValue // Ending pixels to skip
	// contains filtered or unexported fields
}

Crop skips the beginning and the end of the source.

func (*Crop) Render

func (c *Crop) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Curve

type Curve string

Curve models visually pleasing curves.

They are modeled against CSS transitions. https://www.w3.org/TR/web-animations/#scaling-using-a-cubic-bezier-curve

const (
	Ease       Curve = "ease"
	EaseIn     Curve = "ease-in"
	EaseInOut  Curve = "ease-in-out"
	EaseOut    Curve = "ease-out" // Recommended and default value.
	Direct     Curve = "direct"   // linear mapping
	StepStart  Curve = "steps(1,start)"
	StepMiddle Curve = "steps(1,middle)"
	StepEnd    Curve = "steps(1,end)"
)

All the kind of known curves.

func (Curve) Scale

func (c Curve) Scale(intensity uint16) uint16

Scale scales input [0, 65535] to output [0, 65535] using the curve requested.

func (Curve) Scale8

func (c Curve) Scale8(intensity uint16) uint8

Scale8 saves on casting.

type Dim

type Dim struct {
	Child     SPattern //
	Intensity SValue   // 0 is transparent, 255 is fully opaque with original colors.
}

Dim is a filter that dim the intensity of a buffer.

func (*Dim) Render

func (d *Dim) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Frame

type Frame []Color

Frame is a strip of colors. It knows how to renders itself into a frame (which is recursive).

func (Frame) Add

func (f Frame) Add(r Frame)

Add adds two frames together with saturation.

func (Frame) At added in v1.0.1

func (f Frame) At(x, y int) color.Color

At implements image.Image.

func (Frame) Bounds added in v1.0.1

func (f Frame) Bounds() image.Rectangle

Bounds implements image.Image.

func (Frame) ColorModel added in v1.0.1

func (f Frame) ColorModel() color.Model

ColorModel implements image.Image.

func (Frame) Dim

func (f Frame) Dim(intensity uint8)

Dim reduces the intensity of a frame to scale it on intensity.

func (*Frame) FromString

func (f *Frame) FromString(s string) error

FromString converts a "LRRGGBB..." encoded string to a Frame.

'f' is untouched in case of error.

func (Frame) MarshalJSON

func (f Frame) MarshalJSON() ([]byte, error)

MarshalJSON encodes the frame as a string "LRRGGBB...".

func (Frame) Mix

func (f Frame) Mix(b Frame, gradient uint8)

Mix blends the second frame with the first.

gradient 0 means pure 'f', gradient 255 means pure 'b'.

It is the equivalent of:

c.Dim(255-gradient)
d.Dim(gradient)
c.Add(d)

except that this function doesn't affect d.

func (Frame) Render

func (f Frame) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

func (Frame) String

func (f Frame) String() string

func (Frame) ToRGB

func (f Frame) ToRGB(b []byte)

ToRGB converts the Frame to a raw RGB stream.

func (*Frame) UnmarshalJSON

func (f *Frame) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes the string "LRRGGBB..." to the colors.

If unmarshalling fails, 'f' is not touched.

type Gradient

type Gradient struct {
	Left  SPattern
	Right SPattern
	Curve Curve
	// contains filtered or unexported fields
}

Gradient does a gradient between 2 patterns.

A good example is using two colors but it can also be animations.

TODO(maruel): Support N colors at M positions.

func (*Gradient) Render

func (g *Gradient) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Interpolation

type Interpolation string

Interpolation specifies a way to scales a pixel strip.

const (
	NearestSkip Interpolation = "nearestskip" // Selects the nearest pixel but when upscaling, skips on missing pixels.
	Nearest     Interpolation = "nearest"     // Selects the nearest pixel, gives a blocky view.
	Linear      Interpolation = "linear"      // Linear interpolation, recommended and default value.
)

All the kinds of interpolations.

func (Interpolation) Scale

func (i Interpolation) Scale(in, out Frame)

Scale interpolates a frame into another using integers as much as possible for reasonable performance.

type Lightning

type Lightning struct {
	Center    SValue // offset of the center, from the left
	HalfWidth SValue // in pixels
	Intensity int    // the maximum intensity
	StartMS   SValue // when it started
}

Lightning is an experimental generator.

func (*Lightning) Render

func (l *Lightning) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Loop

type Loop struct {
	Patterns     []SPattern
	ShowMS       uint32 // Duration for each pattern to be shown as pure
	TransitionMS uint32 // Duration of the transition between two patterns, can be 0
	Curve        Curve  // Type of transition, defaults to EaseOut if not set
	// contains filtered or unexported fields
}

Loop rotates between all the animations.

Display starts with one ShowMS for Patterns[0], then starts looping. timeMS is not modified so it's like as all animations continued animating behind. TODO(maruel): Add lateral transition and others.

func LoadPNG

func LoadPNG(content []byte, frameDuration time.Duration, vertical bool) *Loop

LoadPNG loads a PNG file and creates a Loop out of the lines.

If vertical is true, rotate the image by 90°.

func (*Loop) Render

func (l *Loop) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type MovePerHour

type MovePerHour SValue

MovePerHour is the number of movement per hour.

Can be either positive or negative. Maximum supported value is ±3600000, 1000 move/sec.

Sample values:

  • 1: one move per hour
  • 60: one move per minute
  • 3600: one move per second
  • 216000: 60 move per second

func (*MovePerHour) Eval

func (m *MovePerHour) Eval(timeMS uint32, l int, cycle int) int

Eval is not a Value implementation but it leverages an inner one.

func (*MovePerHour) MarshalJSON

func (m *MovePerHour) MarshalJSON() ([]byte, error)

MarshalJSON is because MovePerHour is a superset of SValue.

func (*MovePerHour) UnmarshalJSON

func (m *MovePerHour) UnmarshalJSON(b []byte) error

UnmarshalJSON is because MovePerHour is a superset of SValue.

type NightStars

type NightStars struct {
	C Color
	// contains filtered or unexported fields
}

NightStars is an experimental generator.

func (*NightStars) Render

func (n *NightStars) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type OpAdd

type OpAdd struct {
	AddMS int32
}

OpAdd adds a constant to timeMS.

func (*OpAdd) Eval

func (o *OpAdd) Eval(timeMS uint32, l int) int32

Eval implements Value.

func (*OpAdd) MarshalJSON

func (o *OpAdd) MarshalJSON() ([]byte, error)

MarshalJSON encodes the add as a string.

func (*OpAdd) UnmarshalJSON

func (o *OpAdd) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes the add in the form of a string.

If unmarshalling fails, 'o' is not touched.

type OpMod

type OpMod struct {
	TickMS int32 // The cycling time. Maximum is ~25 days.
}

OpMod is a value that is cycling downward.

func (*OpMod) Eval

func (o *OpMod) Eval(timeMS uint32, l int) int32

Eval implements Value.

func (*OpMod) MarshalJSON

func (o *OpMod) MarshalJSON() ([]byte, error)

MarshalJSON encodes the mod as a string.

func (*OpMod) UnmarshalJSON

func (o *OpMod) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes the mod in the form of a string.

If unmarshalling fails, 'o' is not touched.

type OpStep

type OpStep struct {
	TickMS int32 // The cycling time. Maximum is ~25 days.
}

OpStep is a value that is cycling upward.

It is useful for offsets that are increasing as a stepping function.

func (*OpStep) Eval

func (o *OpStep) Eval(timeMS uint32, l int) int32

Eval implements Value.

type Pattern

type Pattern interface {
	// Render fills the buffer with the image at this time frame.
	//
	// The image should be derived from timeMS, which is the time since this
	// pattern was started.
	//
	// Calling Render() with a nil pattern is valid. Patterns should be callable
	// without crashing with an object initialized with default values.
	//
	// timeMS will cycle after 49.7 days. The reason it's not using time.Duration
	// is that int64 calculation on ARM is very slow and abysmal on xtensa, which
	// this code is transpiled to.
	Render(pixels Frame, timeMS uint32)
}

Pattern is a interface to draw an animated line.

type Percent

type Percent int32

Percent is a percentage of the length. It is stored as a 16.16 fixed point.

func (Percent) Eval

func (p Percent) Eval(timeMS uint32, l int) int32

Eval implements Value.

func (*Percent) MarshalJSON

func (p *Percent) MarshalJSON() ([]byte, error)

MarshalJSON encodes the percent as a string.

func (*Percent) UnmarshalJSON

func (p *Percent) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes the percent in the form of a string.

If unmarshalling fails, 'p' is not touched.

type PingPong

type PingPong struct {
	Child       SPattern    // [0] is the front pixel so the pixels are effectively drawn in reverse order
	MovePerHour MovePerHour // Expressed in number of light jumps per hour
	// contains filtered or unexported fields
}

PingPong shows a 'ball' with a trail that bounces from one side to the other.

Can be used for a ball, a water wave or K2000 (Knight Rider) style light. The trail can be a Frame or a dynamic pattern.

To get smoothed movement, use Scale{} with a 5x factor or so. TODO(maruel): That's a bit inefficient, enable Interpolation here.

func (*PingPong) Render

func (p *PingPong) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Rainbow

type Rainbow struct {
	// contains filtered or unexported fields
}

Rainbow renders rainbow colors.

func (*Rainbow) MarshalJSON

func (r *Rainbow) MarshalJSON() ([]byte, error)

MarshalJSON encodes the rainbow as a string "Rainbow".

func (*Rainbow) Render

func (r *Rainbow) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

func (*Rainbow) String

func (r *Rainbow) String() string

func (*Rainbow) UnmarshalJSON

func (r *Rainbow) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes the string "Rainbow" to the rainbow.

type Rand

type Rand struct {
	TickMS int32 // The resolution at which the random value changes.
}

Rand is a value that pseudo-randomly changes every TickMS millisecond. If unspecified, changes every 60fps.

func (*Rand) Eval

func (r *Rand) Eval(timeMS uint32, l int) int32

Eval implements Value.

func (*Rand) MarshalJSON

func (r *Rand) MarshalJSON() ([]byte, error)

MarshalJSON encodes the rand as a string.

func (*Rand) UnmarshalJSON

func (r *Rand) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes the string to the rand.

If unmarshalling fails, 'r' is not touched.

type Repeated

type Repeated struct {
	Frame Frame
}

Repeated repeats a Frame to fill the pixels.

func (*Repeated) Render

func (r *Repeated) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Rotate

type Rotate struct {
	Child       SPattern
	MovePerHour MovePerHour // Expressed in number of light jumps per hour.
	// contains filtered or unexported fields
}

Rotate rotates a pattern that can also cycle either way.

Use negative to go left. Can be used for 'candy bar'.

Similar to PingPong{} except that it doesn't bounce.

Use 5x oversampling with Scale{} to create smoother animation.

func (*Rotate) Render

func (r *Rotate) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type SPattern

type SPattern struct {
	Pattern
}

SPattern is a Pattern that can be serialized.

It is only meant to be used in mixers.

func (*SPattern) MarshalJSON

func (s *SPattern) MarshalJSON() ([]byte, error)

MarshalJSON includes the additional key "_type" to help with unmarshalling.

func (*SPattern) Render

func (s *SPattern) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

func (*SPattern) UnmarshalJSON

func (s *SPattern) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes a Pattern.

It knows how to decode Color, Frame or other arbitrary Pattern.

If unmarshalling fails, 's' is not touched.

type SValue

type SValue struct {
	Value
}

SValue is the serializable version of Value.

func (*SValue) Eval

func (s *SValue) Eval(timeMS uint32, l int) int32

Eval implements Value.

func (*SValue) MarshalJSON

func (s *SValue) MarshalJSON() ([]byte, error)

MarshalJSON includes the additional key "_type" to help with unmarshalling.

func (*SValue) UnmarshalJSON

func (s *SValue) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes a Value.

It knows how to decode Const or other arbitrary Value.

If unmarshalling fails, 'f' is not touched.

type Scale

type Scale struct {
	Child SPattern
	// Defaults to Linear
	Interpolation Interpolation
	// A buffer of this len(buffer)*RatioMilli/1000 will be provided to Child and
	// will be scaled; 500 means smaller, 2000 is larger.
	//
	// Can be set to 0 when Child is a Frame. In this case it is stretched to the
	// strip size.
	RatioMilli SValue
	// contains filtered or unexported fields
}

Scale adapts a larger or smaller patterns to the Strip size

This is useful to create smoother horizontal movement animation or to scale up/down images.

func (*Scale) Render

func (s *Scale) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Split

type Split struct {
	Left   SPattern
	Right  SPattern
	Offset SValue // Point to split between both sides.
}

Split splits the strip in two.

Unlike gradient, this create 2 logical independent subsets.

func (*Split) Render

func (s *Split) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Subset

type Subset struct {
	Child  SPattern
	Offset SValue // Starting pixels to skip
	Length SValue // Length of the pixels to carry over
}

Subset skips the beginning and the end of the destination.

func (*Subset) Render

func (s *Subset) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type ThumbnailsCache

type ThumbnailsCache struct {
	NumberLEDs       int // Must be set before calling Thumbnail().
	ThumbnailHz      int // Must be set before calling Thumbnail().
	ThumbnailSeconds int // Must be set before calling Thumbnail().
	// contains filtered or unexported fields
}

ThumbnailsCache is a cache of animated GIF thumbnails for each pattern.

func (*ThumbnailsCache) GIF

func (t *ThumbnailsCache) GIF(serialized []byte) ([]byte, error)

GIF returns a serialized animated GIF for a JSON serialized pattern.

type Thunderstorm

type Thunderstorm struct {
	AvgMS int // Average between lightning strikes

}

Thunderstorm creates strobe-like lightning.

func (*Thunderstorm) Render

func (t *Thunderstorm) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Transition

type Transition struct {
	Before       SPattern // Old pattern that is disappearing
	After        SPattern // New pattern to show
	OffsetMS     uint32   // Offset at which the transiton from Before->In starts
	TransitionMS uint32   // Duration of the transition while both are rendered
	Curve        Curve    // Type of transition, defaults to EaseOut if not set
	// contains filtered or unexported fields
}

Transition changes from Before to After over time. It doesn't repeat.

In gets timeMS that is subtracted by OffsetMS.

func (*Transition) Render

func (t *Transition) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

type Value

type Value interface {
	Eval(timeMS uint32, l int) int32
}

Value defines a value that may be constant or that may evolve over time.

type WishingStar

type WishingStar struct {
	Duration     time.Duration // Average duration of a star.
	AverageDelay time.Duration // Average delay between each wishing star.
}

WishingStar draws a wishing star from time to time.

It will only draw one star at a time. To increase the likelihood of getting many simultaneously, create multiple instances.

func (*WishingStar) Render

func (w *WishingStar) Render(pixels Frame, timeMS uint32)

Render implements Pattern.

Directories

Path Synopsis
cmd
anim1d
anim1d renders an anim1d animation to the terminal or LEDs strip.
anim1d renders an anim1d animation to the terminal or LEDs strip.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL