-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathanimation.go
86 lines (69 loc) · 2.12 KB
/
animation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//go:build !tinygo
// +build !tinygo
package gfx
import (
"image"
"image/color"
"image/draw"
"image/gif"
"io"
)
// DefaultAnimationDelay is the default animation delay, in 100ths of a second.
var DefaultAnimationDelay = 50
// Animation represents multiple images.
type Animation struct {
Frames []image.Image // The successive images.
Palettes []color.Palette // The successive palettes.
Delay int // Delay between each of the frames.
// LoopCount controls the number of times an animation will be
// restarted during display.
// A LoopCount of 0 means to loop forever.
// A LoopCount of -1 means to show each frame only once.
// Otherwise, the animation is looped LoopCount+1 times.
LoopCount int
}
// AddPalettedImage adds a frame and palette to the animation.
func (a *Animation) AddPalettedImage(frame PalettedImage) {
a.Frames = append(a.Frames, frame)
a.Palettes = append(a.Palettes, frame.ColorPalette())
}
// AddFrame adds a frame to the animation.
func (a *Animation) AddFrame(frame image.Image, palette color.Palette) {
a.Frames = append(a.Frames, frame)
a.Palettes = append(a.Palettes, palette)
}
// SaveGIF saves the animation to a GIF using the provided file name.
func (a *Animation) SaveGIF(fn string) error {
w, err := CreateFile(fn)
if err != nil {
return err
}
defer w.Close()
return a.EncodeGIF(w)
}
// EncodeGIF writes the animation to w in GIF format with the
// given loop count and delay between frames.
func (a *Animation) EncodeGIF(w io.Writer) error {
if len(a.Frames) != len(a.Palettes) {
return Error("Animation: the number of Frames and Palettes does not match")
}
if a.Delay < 1 {
a.Delay = DefaultAnimationDelay
}
var frames []*image.Paletted
var delays []int
var disposal []byte
for i, src := range a.Frames {
dst := image.NewPaletted(src.Bounds(), a.Palettes[i])
draw.Draw(dst, dst.Bounds(), src, image.ZP, draw.Src)
frames = append(frames, dst)
delays = append(delays, a.Delay)
disposal = append(disposal, gif.DisposalBackground)
}
return gif.EncodeAll(w, &gif.GIF{
Image: frames,
Delay: delays,
LoopCount: a.LoopCount,
Disposal: disposal,
})
}