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

  1. package effects
  2. import (
  3. "fmt"
  4. "git.aiterp.net/lucifer3/server/device"
  5. "math"
  6. "time"
  7. )
  8. type Gradient struct {
  9. States []device.State `json:"states,omitempty"`
  10. AnimationMS int64 `json:"AnimationMs,omitempty"`
  11. Reverse bool `json:"backward,omitempty"`
  12. Interpolate bool `json:"interpolate,omitempty"`
  13. }
  14. func (e Gradient) State(index, length, round, _ int) device.State {
  15. if len(e.States) == 0 {
  16. return device.State{}
  17. }
  18. if e.Reverse {
  19. index = length - (index + 1)
  20. }
  21. walkedIndex := (index + round) % length
  22. indexFactor := math.Min(float64(walkedIndex)/float64(length-1), 1)
  23. stateIncrement := 1.0 / float64(len(e.States)-1)
  24. for i := range e.States {
  25. a := float64(i) * stateIncrement
  26. if indexFactor >= a {
  27. si := e.States[i]
  28. sj := e.States[(i+1)%len(e.States)]
  29. f := (indexFactor - a) / stateIncrement
  30. if f < 0 || f > 1 {
  31. panic(f)
  32. }
  33. if e.Interpolate {
  34. return si.Interpolate(sj, f)
  35. } else if f < 0.5 {
  36. return si
  37. } else {
  38. return sj
  39. }
  40. }
  41. }
  42. return e.States[len(e.States)-1]
  43. }
  44. func (e Gradient) Frequency() time.Duration {
  45. return time.Duration(e.AnimationMS) * time.Millisecond
  46. }
  47. func (e Gradient) EffectDescription() string {
  48. return fmt.Sprintf("Gradient(states:%s, anim:%dms, int:%t)", statesDescription(e.States), e.AnimationMS, e.Interpolate)
  49. }