animations

package module
v2.0.0 Latest Latest
Warning

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

Go to latest
Published: Mar 17, 2023 License: MIT Imports: 7 Imported by: 0

README

Go Report Card GoDoc Go Version Unstable release Stable release

GIU Animations

This is a module for giu providing an animation system.

Contributors

     

@gucio321
Head Developer

@sirthunderek
Logo Designer

@Garnn
Editor

Documentation

How to use?

For complete code, please check out examples

important note

Please make sure that you're using the same version of giu as this project (technically, you need to use giu version that uses the same imgui-go version as yours)

Defining an animation

At the moment, there are three implementations of animations:

  • Transition - a smooth transition between two windows/sets of windows e.t.c. NOTE applying this animation to single widgets is not implemented yet and may not work as expected.
  • Color Flow - you can apply this animation to any widget You can configure this animation to make your button hover smoothly or change it into a rainbow!
  • Movement - moves DrawCursor, emulating moving an object (aka giu.Widget).

Lets shortly discuss particular types of animations:

Transition

Lets look at the API:

func Transition(renderers ...func(starter func(mode PlayMode))) *TransitionAnimation {...}

renderers are just key frames of trasition. In each stage appropiate renderer is called. The argument to the renderers is a pointer to Animator.Start (see later) so that you can call it to play the animation.

Color flow
func ColorFlow(
        widget giu.Widget,
        applying []giu.StyleColorID,
        colors ...func() color.RGBA,
) *ColorFlowAnimation {...}
  • The first argument is a function producing a widget that the animation should apply to
  • next is the list of style-color identifiers. Color changes apply to all of them.
  • and the last list of arguments are key frames of color flow.

There is also a variant of the above method called ColorFlowStyle, which does not need colors list. These colors are obtained by function like this:

func() color.RGBA {
    return imgui.CurrentStyle().GetStyleColor(styleID)
}
Move
func Move(w func(starter StarterFunc) giu.Widget, steps ...*MoveStep) *MoveAnimation {...}

This will move w around the steps. Lets take a closer look on steps now:

  • You create a step with Step or StepVec methods.
  • You have two options of specifying position:
    • you can make it relative to the previous step. This way the system will take position and add it to the position of the previous step (and do it until it reaches first step or any step with absolute position)
    • After calling Absolute() method of the MoveStep, its position becomes absolute so that it does not rely on any previous step.
  • An additional feature of Steps is a Bezier Curve implementation. In order to enable it, simply call Bezier method and specify as many points as you wish.

One more important thing to mention is the first step. By default, position of the first step you specify will be treated absolute, even though it wasn't set to be. To change this there are two additional methods of MoveAnimation.

  • the first one is called StartPos and takes one argument of the following type: func(startPos imgui.Vec2) *MoveStep. It is expected to return non-nil MoveStep. startPos argument is the position of drawing cursor at the moment of first call of Animator.
  • another method is tu simply call DefaultStartPos method. It takes no arguments and acts like most users would like to use StartPos - it returns Step(startPos).
Easing

These are some additional ways of controlling the flow of animation:

const (
        EasingAlgNone EasingAlgorithmType = iota
        EasingAlgInSine
        EasingAlgOutSine
        EasingAlgInOutSine
        EasingAlgInBack
        EasingAlgOutBack
        EasingAlgInOutBack
        EasingAlgInElastic
        EasingAlgOutElastic
        EasingAlgInOutElastic
        EasingAlgInBounce
        EasingAlgOutBounce
        EasingAlgInOutBounce
)

for further reference, see https://easings.net

Note about StarterFunc

This interface holds a reference to the part of AnimatorWidget responsible for starting animations. At the moment, there are three functions

  • Start(PlayMode) go to the next KeyFrame (forwards or backwards)
  • StartCycle(numberOfCycles int, mode PlayMode) - play animation numberOfCycles times starting and ending on this frame.
  • StartKF(base, destination KeyFrame, numberOfCycles int, mode PlayMode) go from base to destination in mode direction (frame by frame) making numberOfCycles cycles
Using animator

After constructing an animation, you need to create a special type of giu widget called AnimatorWidget.

You may want to store it in a temporary variable, but, as you'll see later, animator's api is designed so that you don't need to do so every time.

As an argument to Animator(...) constuctor, you pass previously created animation.

Animator has some useful methods:

  • Duration allows you to specify animation's duration (default is 0.25 s)
  • FPS sets Frames per second value for animation playback (default is 60) NOTE it is not real application's FPS! It just describes how often animation's status is updated.
  • Start - this method you can use to invoke animation play.
  • IsRunning returns true, if animation is being played right now.
ID

AnimatorWidget has a special ID method that allows you to specify your own giu-ID. This ID is used to store an internal animator's state inside of giu context. Using this method is extremely important if you want to avoid confusing panics when using TransitionAnimation along with sub-animators inside that animation. It may happen, that one animator receives the same ID as the previous one. This may lead to unexpected behaviour or even panic! Its good practice to set unique ID everywhere!

Auto triggering

Animator provides a simple way of automated starting of animations. You can do this by using Trigger method. This method takes three arguments:

  • TriggerType (TriggerNever, TriggerOnChange, TriggerOnTrue) tells Animator when to start the animation.
  • play mode - tells how to start it
  • and the last argument is a trigger function func() bool (TIP you can use any of imgui functions like imgui.IsItemHovered)
Key Frame

Key frames are specific frames of an animation, other frames get interpolated according to them. All other states between them are calculated on the go. Key frames system in this module is not very advanced, but it should suit needs of most users. For more information about implementation of this system in particular animation types, see above.

Creating your own animation

You can use this API to create your own animation. To do soo, lets take a look at the Animation interface.

type Animation interface {
        Init()
        Reset()
        KeyFramesCount() int

        BuildNormal(currentKeyFrame KeyFrame, starter func())
        BuildAnimation(animationPercentage, animationPurePercentage float32, startKeyFrame, destinationKeyFrame KeyFrame, starter func())
}

This is a copy from animation.go, but I've removed comments for clarity

Init

init is called once, during first call of Animator.Build you can put some initialization here.

Reset

Reset is called along with (*Animator).Start

KeyFramesCount

Returns a number of key frames the animation implements. This number determines behaviour of Animator while calling Start*

BuildNormal

is called when !(*Animator).IsRunning() It takes a pointer to (*Animator).Start as an argument so you can easily start animation from there.

BuildAnimation

is called instead of BuildNormal when playing an animation. Along with pointer to (*Animator).Start, it also receives current animation progress in percents (0 >= currentPercentage <= 1) You can do some calculations there.

Contribution

If you implement something interesting, find any bugs, or improvements and if you would be so kind to open a PR, your contribution is welcome!

Motivation

For now, this system is used in one of The Greater Heptavirate's projects. But (as I'm an author of that system) I've decided to share it for public - feel free to use if you can find any use case.

License

This project is shared under (attached) MIT License.

Documentation

Overview

Package animations contains my attempt to create animation kind of "animations" in imgui.

Index

Constants

View Source
const (
	// DefaultFPS is FPS value that should suit most use-cases.
	// Animator takes this value by default and it could be changed by (*Animator).FPS().
	DefaultFPS = 60
	// DefaultDuration is animation's duration set by default.
	// You can change this by (*Animator).Durations().
	DefaultDuration = time.Second / 4
)

Variables

This section is empty.

Functions

func Ease

func Ease(alg EasingAlgorithmType, t float32) float32

Ease takes EasingAlgorithmType and plain percentage value t and returns eased value. The following condition is expected to be met, however they are not restricted anyhow: 0 <= t <= 1.

Types

type Animation

type Animation interface {
	// Init is called once, immediately on start.
	Init()
	// Reset is called whenever needs to restart animation.
	Reset()

	// KeyFramesCount is used mainly by the AnimatorWidget.
	// It returns animation number of key frames.
	KeyFramesCount() int

	// BuildNormal is called every frame when animation is not running
	// starter is animation link to Animator.Start
	BuildNormal(currentKeyFrame KeyFrame, starterFunc StarterFunc)
	// BuildAnimation is called when running an animation.
	// It receives several important arguments:
	// - animationPercentage after applying specified by Animator
	//   easing algorithm.
	//   ATTENTION: this value may be less than 0 or greater than 1
	// - pure percentage status of animation before applying
	//   any algorithm.
	//   it is always in range <0, 1> (0 <= arbitraryPercentage <= 1)
	//   NOTE: this value should NOT be used in most cases, because it will
	//   disable user from specifying Easing Algorithm and most use-cases
	//   does not want this, however you may want to use for comparing something.
	// - base and destination Key Frames - your animation should be played from first to the second.
	// - animation's Play Mode - use it if it is important to know what is the exact play direction.
	// - starter functions set (see StarterFunc)
	// starter is animation link to (*Animator).Start() method.
	BuildAnimation(
		animationPercentage, arbitraryPercentage float32,
		baseKeyFrame, destinationKeyFrame KeyFrame,
		mode PlayMode,
		starterFunc StarterFunc,
	)
}

Animation is an interface implemented by each animation. Every type that implements Animation interface is liable to be used as an argument of Animator method.

type AnimatorWidget

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

AnimatorWidget is animation manager for Animation. It is a giu.Widget (so you can use it in any giu.Layout). This type provides a wide API that allows you to manage your animation such as Start* functions or parameters like FPS or Duration. It is actually responsible for advancement of animation. NOTE: This type should be concurrent-safe. If you find any data race please open an issue in source repository.

func Animator

func Animator(a Animation) *AnimatorWidget

Animator creates animation new AnimatorWidget.

func (*AnimatorWidget) Build

func (a *AnimatorWidget) Build()

Build implements giu.Widget.

func (*AnimatorWidget) CurrentPercentageProgress

func (a *AnimatorWidget) CurrentPercentageProgress() float32

CurrentPercentageProgress returns animation float value from range <0, 1> representing current progress of an animation. If animation is not running, it will return 0.

func (*AnimatorWidget) Duration

func (a *AnimatorWidget) Duration(duration time.Duration) *AnimatorWidget

Duration allows to specify duration value. CAUTION: it will take effect after next call to Start - not applied to currently plaid animation.

func (*AnimatorWidget) EasingAlgorithm

func (a *AnimatorWidget) EasingAlgorithm(alg EasingAlgorithmType) *AnimatorWidget

EasingAlgorithm allows to specify easing algorithm.

func (*AnimatorWidget) FPS

func (a *AnimatorWidget) FPS(fps int) *AnimatorWidget

FPS allows to specify FPS value. CAUTION: it will take effect after next call to Start - not applied to currently plaid animation.

func (*AnimatorWidget) ID

func (a *AnimatorWidget) ID(newID string) *AnimatorWidget

ID sets animation custom ID to this AnimatorWidget It may be really important when using TransitionAnimation, because sometimes when using sub-animators inside of Transition, it may happen that the second AnimatorWidget will receive the same ID as the previous one. It may cause unexpected behaviours.

func (*AnimatorWidget) IsRunning

func (a *AnimatorWidget) IsRunning() bool

IsRunning returns true if the animation is already running.

func (*AnimatorWidget) Start

func (a *AnimatorWidget) Start(playMode PlayMode)

Start starts the animation. It plays one single frame forwards/backwards (depending on playMode).

func (*AnimatorWidget) StartCycle

func (a *AnimatorWidget) StartCycle(numberOfCycles int, playMode PlayMode)

StartCycle plays an animation from start to end (optionally from end to start)

func (*AnimatorWidget) StartKeyFrames

func (a *AnimatorWidget) StartKeyFrames(beginKF, destinationKF KeyFrame, cyclesCount int, playMode PlayMode)

StartKeyFrames initializes animation playback from beginKF to destination KF in direction specified by playMode.

func (*AnimatorWidget) Trigger

func (a *AnimatorWidget) Trigger(triggerType TriggerType, playMode PlayMode, f TriggerFunc) *AnimatorWidget

Trigger sets automatic triggering of animation.

Example: (*AnimatorWidget).Trigger(TriggerOnChange, imgui.IsItemHovered)

type ColorFlowAnimation

type ColorFlowAnimation struct {
	giu.Widget
	// contains filtered or unexported fields
}

ColorFlowAnimation makes a smooth flow from one color to another on all specified StyleColor variables.

func ColorFlow

func ColorFlow(
	widget giu.Widget,
	applying []giu.StyleColorID,
	colors ...func() color.RGBA,
) *ColorFlowAnimation

ColorFlow creates a new ColorFlowAnimation.

func ColorFlowColors

func ColorFlowColors(
	widget giu.Widget,
	applying []giu.StyleColorID,
	colors ...color.Color,
) *ColorFlowAnimation

ColorFlowColors takes a colors list instead of list of functions returning colors.

func ColorFlowStyle

func ColorFlowStyle(
	widget giu.Widget,
	normal, destiny giu.StyleColorID,
) *ColorFlowAnimation

ColorFlowStyle wraps ColorFlow so that it automatically obtains the color for specified style values.

func (*ColorFlowAnimation) BuildAnimation

func (c *ColorFlowAnimation) BuildAnimation(
	percentage, _ float32,
	sourceKeyFrame, destinyKeyFrame KeyFrame,
	_ PlayMode,
	_ StarterFunc,
)

BuildAnimation implements Animation.

func (*ColorFlowAnimation) BuildNormal

func (c *ColorFlowAnimation) BuildNormal(currentKeyFrame KeyFrame, _ StarterFunc)

BuildNormal builds animation in normal, not-triggered state.

func (*ColorFlowAnimation) Init

func (c *ColorFlowAnimation) Init()

Init implements Animation.

func (*ColorFlowAnimation) KeyFramesCount

func (c *ColorFlowAnimation) KeyFramesCount() int

KeyFramesCount implements Animation.

func (*ColorFlowAnimation) Reset

func (c *ColorFlowAnimation) Reset()

Reset implements Animation.

type EasingAlgorithm

type EasingAlgorithm func(plainPercentage float32) (percentage float32)

type EasingAlgorithmType

type EasingAlgorithmType byte

EasingAlgorithmType represents animation type of easing algorithm used for animation. Refer https://easings.net/

const (
	EasingAlgNone EasingAlgorithmType = iota
	EasingAlgInSine
	EasingAlgOutSine
	EasingAlgInOutSine
	EasingAlgInBack
	EasingAlgOutBack
	EasingAlgInOutBack
	EasingAlgInElastic
	EasingAlgOutElastic
	EasingAlgInOutElastic
	EasingAlgInBounce
	EasingAlgOutBounce
	EasingAlgInOutBounce
	EasingAlgMax
)

type KeyFrame

type KeyFrame byte

KeyFrame represents the most important states of an animation. Each animation declares an algorithm of calculating states between its KeyFrames.

type MoveAnimation

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

MoveAnimation moves animation widget from start position to destination. You can also specify animation Bézier curve's points.

func Move

func Move(w func(starter StarterFunc) giu.Widget, steps ...*MoveStep) *MoveAnimation

Move creates new *MoveAnimations NOTE: You may want to take animation look on StartPos or DefaultStartPos methods to specify animation starting position. otherwise the first step specified will be treated as start position.

func (*MoveAnimation) BuildAnimation

func (m *MoveAnimation) BuildAnimation(
	animationPercentage, _ float32,
	srcFrame, destFrame KeyFrame,
	mode PlayMode,
	starter StarterFunc,
)

BuildAnimation implements Animation.

func (*MoveAnimation) BuildNormal

func (m *MoveAnimation) BuildNormal(currentKF KeyFrame, starter StarterFunc)

BuildNormal implements Animation.

func (*MoveAnimation) DefaultStartPos

func (m *MoveAnimation) DefaultStartPos() *MoveAnimation

DefaultStartPos will set animation default value of MoveStep as animation starting step. NOTE: You will lose possibility of setting up any additional properties of MoveStep (like bezier points).

func (*MoveAnimation) Init

func (m *MoveAnimation) Init()

Init implements Animation.

func (*MoveAnimation) KeyFramesCount

func (m *MoveAnimation) KeyFramesCount() int

KeyFramesCount implements Animation interface.

func (*MoveAnimation) Reset

func (m *MoveAnimation) Reset()

Reset implements Animation.

func (*MoveAnimation) StartPos

func (m *MoveAnimation) StartPos(startPosStep func(startPos imgui.Vec2) *MoveStep) *MoveAnimation

StartPos allows to specify custom StartPos (item will be moved there immediately). argument function will receive cursor position returned by imgui.GetCursorPos while initializing animation.

type MoveStep

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

MoveStep represents animation single key frame in context of MoveAnimation. If Relative() not set, positionDelta is relative to this in animation previous step.

func Step

func Step(x, y float32) *MoveStep

Step creates animation new instance of MoveStep.

func StepVec

func StepVec(v imgui.Vec2) *MoveStep

StepVec acts same as Step but takes imgui.Vec2.

func (*MoveStep) Absolute

func (m *MoveStep) Absolute() *MoveStep

Absolute tells animation to take position specified in this step as an absolute position rather than relative to he previous step.

func (*MoveStep) Bezier

func (m *MoveStep) Bezier(points ...imgui.Vec2) *MoveStep

Bezier allows to specify Bézier curve points. Points are relative to position specified in step.

type PlayMode

type PlayMode byte

PlayMode represents animation play mode.

const (
	// PlayForward plays animation from 0 to 1 percentage progress.
	PlayForward PlayMode = iota
	// PlayBackward plays an animation from 1 to 0 percentage progress.
	PlayBackward
)

type StarterFunc

type StarterFunc interface {
	Start(mode PlayMode)
	StartKeyFrames(beginKF, destinyKF KeyFrame, cyclesCount int, mode PlayMode)
	StartCycle(cyclesCount int, mode PlayMode)
}

StarterFunc contains animation reference to all Starters of AnimatorWidget

type TransitionAnimation

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

TransitionAnimation is a smooth transition between two renderers. It may apply to Windows (giu.WindowWidget) as well as to particular widgets/layouts.

func Transition

func Transition(renderers ...func(starter StarterFunc)) *TransitionAnimation

Transition creates a new TransitionAnimation.

func (*TransitionAnimation) BuildAnimation

func (t *TransitionAnimation) BuildAnimation(
	percentage, _ float32,
	bf, df KeyFrame,
	_ PlayMode,
	starter StarterFunc,
)

BuildAnimation implements Animation interface.

func (*TransitionAnimation) BuildNormal

func (t *TransitionAnimation) BuildNormal(f KeyFrame, starter StarterFunc)

BuildNormal implements Animation interface.

func (*TransitionAnimation) Init

func (t *TransitionAnimation) Init()

Init implements Animation interface.

func (*TransitionAnimation) KeyFramesCount

func (t *TransitionAnimation) KeyFramesCount() int

KeyFramesCount implements Animation interface.

func (*TransitionAnimation) Reset

func (t *TransitionAnimation) Reset()

Reset implements Animation interface.

type TriggerFunc

type TriggerFunc func() bool

TriggerFunc is a function determining whether the animation should be auto-triggered. See also TriggerType.

type TriggerType

type TriggerType byte

TriggerType represents a strategy of automated triggering of an animation.

const (
	// TriggerNever is animation default value.
	// Animation will not be started automatically.
	TriggerNever TriggerType = iota
	// TriggerOnTrue will start animation whenever trigger becomes true.
	TriggerOnTrue
	// TriggerOnChange will trigger animation, when value of trigger's function
	// will change.
	TriggerOnChange
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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