Skip to content

Animation

Andy Williams edited this page Aug 23, 2020 · 9 revisions

Certain properties of the canvas package may want to be animated. Whilst this is possible using goroutines and calculations with lots of refresh methods this can be complicated and may not run optimally in line with the render process.

This proposal amims to make it much simpler to animate elements that will refresh with the renderer - with the ability to optimise internally for the graphical context.

Basics

The start of animator is anything that uses, or embeds the Animator struct. Every animation has a duration and a Tick callback that the framework will call, starting with a 0.0 parameter and ending with 1.0. We can also set it to repeat. If false the amimation will end when duration lapses, at which point Tick parameter will be 1.0.

type Animator struct {
	Duration time.Duration
	Repeat   bool
	Tick     func(float32)
}

func NewAnimator(d time.Duration, fn func(float32)) *Animator {
	return &Animator{Duration: d, Tick: fn}
}

Specific types

The basic Animator is usable, but specific type versions on top are much more interesting, such as ColorAnimator

func NewColorAnimator(start, stop color.Color, d time.Duration, fn func(color.Color)) *Animator {
	return &Animator{
		Duration: d,
		Tick: func (done float32) {
		r1,g1,b1,a1 := start.RGBA()
		r2,g2,b2,a2 := stop.RGBA()

		rDiff := diff(r1, r2)
		gDiff := diff(g1, g2)
		bDiff := diff(b1, b2)
		aDiff := diff(a1, a2)

		fn(color.NRGBA{R: scale(r1, rDiff, done), G: scale(g1, gDiff, done), B: scale(b1, bDiff, done), A: scale(a1, aDiff, done)})
	}}
}

The specific type of Animator above allows the user to specify a start and stop property and the tick callback will be of the same type. The duration is consistent with the generic type, and is used by the framework to schedule the changes.

To use the above animation you might do the following:

rect := NewRectangle(color.Black)
NewColorAnimation(color.Black, color.White, time.Second, func(c color.Color) {
	rect.FillColor = c
	rect.Refresh()
})

Runtime

When an animation is included on a canvas object it's Tick() is called every frame from when the item becomes visible to when the duration elapses (or when the item is hidden, if that is earlier). If repeat is set the duration will not lapse, but reset after duration and loop.

Questions

  • How can we register animations on the canvas / canvasobject

Perhaps Canvas.Animate(CanvasObject, Animator)?

  • Should we do some reflection to manage properties directly? (i.e. NewColorPropertyAnimation(start, stop, propName, duration, func))
  • What types of things might people do? :)

Welcome to the Fyne wiki.

Project documentation

Getting involved

Platform details

Clone this wiki locally