Files
8bitMyGoUI/media/waveform.go
T
ZacharyZhang-NY 0e21870b64 Add media components 346-365; input.SlideBase, guarded Pad
An audio player with transport, scrubber and volume; an equalizer and
a visualizer; a playlist; a cassette, cartridge and record that turn
while they play and hold where they stop; piano keys, a step sequencer
and a tracker you can type into; a waveform, a 16:9 video frame, an
image compare, a gallery, a filmstrip, a record button and an FM tuner.

input exports SlideBase, the undrawn rail its sliders share; the
gallery treats exported Bases as building blocks, not components.
pixel's micro font gains '#' for notes like C#4. pixel.Pad and the
slide rail read input only while their base is enabled, so Inert or a
fresh Disabled stops a drag or a key already sent. AGENTS records why
a drawn container keeps the DISABLED description: MyGo paints a
disabled subtree at half opacity.
2026-10-12 06:17:12 -04:00

41 lines
968 B
Go

package media
import (
"fmt"
"math"
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
)
type WaveformOptions struct {
// Height is in dots; zero means 32.
Height int
}
// Waveform draws samples, ±1, as lines from the middle.
func Waveform(c *ui.Context, text string, samples []float64, o WaveformOptions) *ui.Element {
k := pixel.K(c)
if len(samples) == 0 {
panic("media: Waveform has no samples")
}
for _, s := range samples {
if !(s >= -1 && s <= 1) {
panic(fmt.Sprintf("media: Waveform sample %v outside ±1", s))
}
}
h := pixel.Or("Waveform Height", o.Height, 32)
half := (h - 1) / 2
return art(c, k, text, 2*len(samples)-1, h).Draw(func(p *ui.Painter, r ui.Rect) {
g := k.Canvas(p, r)
for x := 1; x < g.W; x += 2 {
g.Dot(x, half, pixel.Faint)
}
for i, s := range samples {
n := int(math.Round(s * float64(half)))
g.VLine(2*i, min(half, half-n), max(n, -n)+1, pixel.Accent)
}
})
}