package effects import ( "fmt" "git.aiterp.net/lucifer3/server/device" "math" "time" ) type Gradient struct { States []device.State `json:"states,omitempty"` AnimationMS int64 `json:"AnimationMs,omitempty"` Reverse bool `json:"backward,omitempty"` Interpolate bool `json:"interpolate,omitempty"` } func (e Gradient) State(index, length, round, _ int) device.State { if len(e.States) == 0 { return device.State{} } if e.Reverse { index = length - (index + 1) } walkedIndex := (index + round) % length indexFactor := math.Min(float64(walkedIndex)/float64(length-1), 1) stateIncrement := 1.0 / float64(len(e.States)-1) for i := range e.States { a := float64(i) * stateIncrement if indexFactor >= a { si := e.States[i] sj := e.States[(i+1)%len(e.States)] f := (indexFactor - a) / stateIncrement if f < 0 || f > 1 { panic(f) } if e.Interpolate { return si.Interpolate(sj, f) } else if f < 0.5 { return si } else { return sj } } } return e.States[len(e.States)-1] } func (e Gradient) Frequency() time.Duration { return time.Duration(e.AnimationMS) * time.Millisecond } func (e Gradient) EffectDescription() string { return fmt.Sprintf("Gradient(states:%s, anim:%dms, int:%t)", statesDescription(e.States), e.AnimationMS, e.Interpolate) }