add gradient and random effect.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
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)
|
||||
}
|
||||
+2
-2
@@ -15,14 +15,14 @@ type Manual struct {
|
||||
}
|
||||
|
||||
func (e Manual) EffectDescription() string {
|
||||
return fmt.Sprintf("Manual%s", e.State(0, 0, 0).String())
|
||||
return fmt.Sprintf("Manual%s", e.State(0, 0, 0, 0).String())
|
||||
}
|
||||
|
||||
func (e Manual) Frequency() time.Duration {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e Manual) State(int, int, int) device.State {
|
||||
func (e Manual) State(int, int, int, int) device.State {
|
||||
return device.State{
|
||||
Power: e.Power,
|
||||
Temperature: e.Temperature,
|
||||
|
||||
+12
-8
@@ -7,18 +7,22 @@ import (
|
||||
)
|
||||
|
||||
type Pattern struct {
|
||||
States []device.State `json:"states,omitempty"`
|
||||
ShiftMS int64 `json:"shiftMs,omitempty"`
|
||||
States []device.State `json:"states,omitempty"`
|
||||
AnimationMS int64 `json:"animationMs,omitempty"`
|
||||
}
|
||||
|
||||
func (p Pattern) State(index, round, _ int) device.State {
|
||||
return p.States[(index+round)%len(p.States)]
|
||||
func (e Pattern) State(index, _, round, _ int) device.State {
|
||||
if len(e.States) == 0 {
|
||||
return device.State{}
|
||||
}
|
||||
|
||||
return e.States[(index+round)%len(e.States)]
|
||||
}
|
||||
|
||||
func (p Pattern) Frequency() time.Duration {
|
||||
return time.Duration(p.ShiftMS) * time.Millisecond
|
||||
func (e Pattern) Frequency() time.Duration {
|
||||
return time.Duration(e.AnimationMS) * time.Millisecond
|
||||
}
|
||||
|
||||
func (p Pattern) EffectDescription() string {
|
||||
return fmt.Sprintf("Pattern(len:%d, animation:%dms)", len(p.States), p.ShiftMS)
|
||||
func (e Pattern) EffectDescription() string {
|
||||
return fmt.Sprintf("Pattern(states:%s, anim:%dms)", statesDescription(e.States), e.AnimationMS)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package effects
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.aiterp.net/lucifer3/server/device"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Random struct {
|
||||
States []device.State `json:"states,omitempty"`
|
||||
Interpolate bool `json:"interpolate,omitempty"`
|
||||
AnimationMS int64 `json:"animationMs,omitempty"`
|
||||
}
|
||||
|
||||
func (e Random) State(_, _, _, _ int) device.State {
|
||||
if len(e.States) == 0 {
|
||||
return device.State{}
|
||||
}
|
||||
|
||||
indexFactor := rand.Float64()
|
||||
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 Random) Frequency() time.Duration {
|
||||
return time.Duration(e.AnimationMS) * time.Millisecond
|
||||
}
|
||||
|
||||
func (e Random) EffectDescription() string {
|
||||
return fmt.Sprintf("Random(states:%s, anim:%dms, int:%t)", statesDescription(e.States), e.AnimationMS, e.Interpolate)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package effects
|
||||
|
||||
import (
|
||||
"git.aiterp.net/lucifer3/server/device"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func statesDescription(states []device.State) string {
|
||||
sb := strings.Builder{}
|
||||
sb.Grow(128)
|
||||
|
||||
sb.WriteRune('[')
|
||||
for i, state := range states {
|
||||
if i > 0 {
|
||||
sb.WriteString(", ")
|
||||
}
|
||||
|
||||
sb.WriteString(state.String())
|
||||
}
|
||||
sb.WriteRune(']')
|
||||
|
||||
return sb.String()
|
||||
}
|
||||
Reference in New Issue
Block a user