You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
60 lines
1.3 KiB
60 lines
1.3 KiB
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)
|
|
}
|