Animation

Description of View's properties animation. Two types of animation currently supported:

  • Transition animation - animated property value changes
  • Animation script - script animated change of one or more properties

Properties "duration", "delay" and "timing-function" are used in both types of animations. Properties "id", "property", "iteration-count", "animation-direction" and "animation-paused" are used for animation script

Transition animation also has two types:

  • single shot - animation played only once, see SetAnimated function of View interface
  • constant - play animation every time when some property to which animation has been attached changes its value

Create from source

func NewAnimation(params Params) Animation

Create a new animation object and return its interface

Create from resource

View {
    transition = width{ duration = 0.5, timing-function = ease-in },
}

Interface description

Used to set animation parameters

Inherit methods from Properties, fmt.Stringer

Start(view View, listener func(view View, animation Animation, event string)) bool

Starts the animation for the view specified by the first argument. The second argument specifies the animation event listener(can be nil)

Stop()

Stops the animation

Pause()

Pauses the animation

Resume()

Resumes an animation that was stopped using the Pause() method

Properties

"animation-direction"

Whether an animation should play forward, backward, or alternate back and forth between playing the sequence forward and backward. Used only for animation script

Constant: AnimationDirection

Types: int, string

Values

int string Description
0(NormalAnimation) "normal" The animation plays forward every iteration, that is, when the animation ends, it is immediately reset to its starting position and played again
1(ReverseAnimation) "reverse" The animation plays backwards, from the last position to the first, and then resets to the final position and plays again
2(AlternateAnimation) "alternate" The animation changes direction in each cycle, that is, in the first cycle, it starts from the start position, reaches the end position, and in the second cycle, it continues from the end position and reaches the start position, and so on
3(AlternateReverseAnimation) "alternate-reverse" The animation starts playing from the end position and reaches the start position, and in the next cycle, continuing from the start position, it goes to the end position

"animation-paused"

Controls whether the animation is running or paused

Constant: AnimationPaused

Types: bool, int, string

Values

bool int string Description
true 1 "true", "yes", "on", "1" Animation is paused
false 0 "false", "no", "off", "0" Animation is playing

"delay"

Specifies the amount of time in seconds to wait from applying the animation to an element before beginning to perform the animation. The animation can start later, immediately from its beginning or immediately and partway through the animation

Constant: Delay

Types: float, int, string

Internal type is float, other types converted to it during assignment

Examples

scaleAnim := rui.NewAnimation(rui.Params{
    rui.Duration:       0.2,
    rui.TimingFunction: rui.EaseOutTiming,
})

bgColorAnim := rui.NewAnimation(rui.Params{
    rui.Duration:       0.2,
    rui.Delay:          0.2,
    rui.TimingFunction: rui.LinearTiming,
})

view := rui.NewGridLayout(session, rui.Params{
    rui.Width:               rui.Percent(100),
    rui.Height:              rui.Percent(100),
    rui.CellVerticalAlign:   rui.CenterAlign,
    rui.CellHorizontalAlign: rui.CenterAlign,
    rui.Content: rui.NewButton(session, rui.Params{
        rui.Transition: rui.Params{
            rui.ScaleX:          scaleAnim,
            rui.ScaleY:          scaleAnim,
            rui.BackgroundColor: bgColorAnim,
        },
        rui.Content:         "Push me",
        rui.BackgroundColor: rui.White,
        rui.MouseOver:       hoverIn,
        rui.MouseOut:        hoverOut,
    }),
})
func hoverIn(view rui.View, event rui.MouseEvent) {
    view.Set(rui.ScaleX, 1.2)
    view.Set(rui.ScaleY, 1.2)
    view.Set(rui.BackgroundColor, rui.Orange)
}

func hoverOut(view rui.View, event rui.MouseEvent) {
    view.Set(rui.ScaleX, 1)
    view.Set(rui.ScaleY, 1)
    view.Set(rui.BackgroundColor, rui.White)
}

"duration"

Sets the length of time in seconds that an animation takes to complete one cycle

Constant: Duration

Types: float, int, string

Internal type is float, other types converted to it during assignment

Examples

view := rui.NewGridLayout(session, rui.Params{
    rui.Width:               rui.Percent(100),
    rui.Height:              rui.Percent(100),
    rui.CellVerticalAlign:   rui.CenterAlign,
    rui.CellHorizontalAlign: rui.CenterAlign,
    rui.Content: rui.NewButton(session, rui.Params{
        rui.Transition: rui.Params{
            rui.BackgroundColor: rui.NewAnimation(rui.Params{
                rui.Duration:       0.2,
                rui.TimingFunction: rui.LinearTiming,
            }),
        },
        rui.Content:         "Push me",
        rui.BackgroundColor: rui.White,
        rui.MouseOver:       hoverIn,
        rui.MouseOut:        hoverOut,
    }),
})
func hoverIn(view rui.View, event rui.MouseEvent) {
    view.Set(rui.BackgroundColor, rui.Orange)
}

func hoverOut(view rui.View, event rui.MouseEvent) {
    view.Set(rui.BackgroundColor, rui.White)
}

"id"

Specifies the animation identifier. Used only for animation script

Constant: ID

Types: string

Examples

view := rui.NewGridLayout(session, rui.Params{
    rui.Width:               rui.Percent(100),
    rui.Height:              rui.Percent(100),
    rui.CellVerticalAlign:   rui.CenterAlign,
    rui.CellHorizontalAlign: rui.CenterAlign,
    rui.Content: rui.NewListLayout(session, rui.Params{
        rui.ListColumnGap:   rui.Em(1),
        rui.VerticalAlign:   rui.CenterAlign,
        rui.HorizontalAlign: rui.CenterAlign,
        rui.Content: []rui.View{
            rui.NewButton(session, rui.Params{
                rui.Content:             "Push me",
                rui.BackgroundColor:     rui.White,
                rui.MouseOver:           hoverIn,
                rui.MouseOut:            hoverOut,
                rui.AnimationStartEvent: animationStartEvent,
                rui.AnimationEndEvent:   animationEndEvent,
            }),
            rui.NewTextView(session, rui.Params{
                rui.ID:   "action",
                rui.Text: "Idle",
            }),
        },
    }),
})
func hoverIn(view rui.View, event rui.MouseEvent) {
    highlightAnim := rui.NewAnimation(rui.Params{
        rui.ID:             "in-animation",
        rui.Duration:       1,
        rui.TimingFunction: rui.LinearTiming,
        rui.PropertyTag: rui.AnimatedProperty{
            Tag:  rui.BackgroundColor,
            From: rui.White,
            To:   rui.Orange,
        },
    })

    view.Set(rui.AnimationTag, highlightAnim)
}

func hoverOut(view rui.View, event rui.MouseEvent) {
    highlightAnim := rui.NewAnimation(rui.Params{
        rui.ID:             "out-animation",
        rui.Duration:       1,
        rui.TimingFunction: rui.LinearTiming,
        rui.PropertyTag: rui.AnimatedProperty{
            Tag:  rui.BackgroundColor,
            From: rui.Orange,
            To:   rui.White,
        },
    })

    view.Set(rui.AnimationTag, highlightAnim)
}

func animationStartEvent(view rui.View, animationId string) {
    rootView := view.Session().RootView()
    if textView := rui.TextViewByID(rootView, "action"); textView != nil {
        switch animationId {
        case "in-animation":
            textView.Set(rui.Text, "Highlighting...")
        case "out-animation":
            textView.Set(rui.Text, "Rolling back highlight...")
        }
    }
}

func animationEndEvent(view rui.View, animationId string) {
    rootView := view.Session().RootView()
    if textView := rui.TextViewByID(rootView, "action"); textView != nil {
        switch animationId {
        case "in-animation":
            textView.Set(rui.Text, "Highlighted")
        case "out-animation":
            textView.Set(rui.Text, "Idle")
        }
    }
}

"iteration-count"

Sets the number of times an animation sequence should be played before stopping. Used only for animation script

Constant: IterationCount

Types: int, string

Internal type is int, other types converted to it during assignment

Examples

view := rui.NewGridLayout(session, rui.Params{
    rui.Width:               rui.Percent(100),
    rui.Height:              rui.Percent(100),
    rui.CellVerticalAlign:   rui.CenterAlign,
    rui.CellHorizontalAlign: rui.CenterAlign,
    rui.Content: rui.NewButton(session, rui.Params{
        rui.Content:   "Push me",
        rui.MouseOver: hoverIn,
        rui.MouseOut:  hoverOut,
    }),
})
func hoverIn(view rui.View, event rui.MouseEvent) {
    highlightAnim := rui.NewAnimation(rui.Params{
        rui.Duration:       1,
        rui.TimingFunction: rui.EaseInOutTiming,
        rui.IterationCount: 2,
        rui.PropertyTag: rui.AnimatedProperty{
            Tag:  rui.Rotate,
            From: rui.Deg(0),
            To:   rui.Deg(360),
        },
    })

    view.Set(rui.AnimationTag, highlightAnim)
}

func hoverOut(view rui.View, event rui.MouseEvent) {
    highlightAnim := rui.NewAnimation(rui.Params{
        rui.Duration:       1,
        rui.TimingFunction: rui.EaseInOutTiming,
        rui.PropertyTag: rui.AnimatedProperty{
            Tag:  rui.Rotate,
            From: rui.Deg(0),
            To:   rui.Deg(-360),
        },
    })

    view.Set(rui.AnimationTag, highlightAnim)
}

"property"

Describes a scenario for changing a View's property. Used only for animation script

Constant: PropertyTag

Types: []AnimatedProperty, AnimatedProperty

Internal type is []AnimatedProperty, other types converted to it during assignment

See AnimatedProperty description for more details

Examples

view := rui.NewGridLayout(session, rui.Params{
    rui.Width:               rui.Percent(100),
    rui.Height:              rui.Percent(100),
    rui.CellVerticalAlign:   rui.CenterAlign,
    rui.CellHorizontalAlign: rui.CenterAlign,
    rui.Content: rui.NewButton(session, rui.Params{
        rui.Content:   "Push me",
        rui.MouseOver: hoverIn,
        rui.MouseOut:  hoverOut,
    }),
})
func hoverIn(view rui.View, event rui.MouseEvent) {
    highlightAnim := rui.NewAnimation(rui.Params{
        rui.Duration:       1,
        rui.TimingFunction: rui.EaseInOutTiming,
        rui.PropertyTag: rui.AnimatedProperty{
            Tag:  rui.Rotate,
            From: rui.Deg(0),
            To:   rui.Deg(360),
        },
    })

    view.Set(rui.AnimationTag, highlightAnim)
}

func hoverOut(view rui.View, event rui.MouseEvent) {
    highlightAnim := rui.NewAnimation(rui.Params{
        rui.Duration:       1,
        rui.TimingFunction: rui.EaseInOutTiming,
        rui.PropertyTag: rui.AnimatedProperty{
            Tag:  rui.Rotate,
            From: rui.Deg(0),
            To:   rui.Deg(-360),
        },
    })

    view.Set(rui.AnimationTag, highlightAnim)
}

"timing-function"

Set how an animation progresses through the duration of each cycle

Constant: TimingFunction

Types: string

Values

string Description
"ease"(EaseTiming) Speed increases towards the middle and slows down at the end
"ease-in"(EaseInTiming) Speed is slow at first, but increases in the end
"ease-out"(EaseOutTiming) Speed is fast at first, but decreases in the end
"ease-in-out"(EaseInOutTiming) Speed is slow at first, but quickly increases and at the end it decreases again
"linear"(LinearTiming) Constant speed
func AddTransition(view View, subviewID, tag string, animation Animation) bool

Adds the transition for the subview property. If the second argument (subviewID) is not specified or is an empty string then the transition is added to the first argument (view)

func CubicBezierTiming(x1, y1, x2, y2 float64) string

Return a cubic-Bezier curve timing function. x1 and x2 must be in the range [0, 1].

func GetAnimation(view View, subviewID ...string) []Animation

Returns the subview animations. The result is always non-nil. If the second argument (subviewID) is not specified or is an empty string then transitions of the first argument (view) is returned

func GetTransition(view View, subviewID, tag string) Animation

Returns the subview property transition. If there is no transition for the given property then nil is returned. If the second argument (subviewID) is not specified or is an empty string then transitions of the first argument (view) is returned

func GetTransitions(view View, subviewID ...string) map[string]Animation

Returns the subview transitions. The result is always non-nil. If the second argument (subviewID) is not specified or is an empty string then transitions of the first argument (view) is returned

func IsAnimationPaused(view View, subviewID ...string) bool

Returns "true" if an animation of the subview is paused, "false" otherwise. If the second argument (subviewID) is not specified or is an empty string then a value from the first argument (view) is returned.

func IsTimingFunctionValid(timingFunction string, session Session) bool

Returns "true" if the "timingFunction" argument is the valid timing function.

func SetAnimated(rootView View, viewID, tag string, value any, animation Animation) bool

Sets the property with name "tag" of the "rootView" subview with "viewID" id by value. Result: true - success, false - error (incompatible type or invalid format of a string value, see AppLog).

func StepsTiming(stepCount int) string

Return a timing function along stepCount stops along the transition, displaying each stop for equal lengths of time