-
Notifications
You must be signed in to change notification settings - Fork 10
/
hue_wave.ex
104 lines (84 loc) · 2.35 KB
/
hue_wave.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
defmodule RGBMatrix.Animation.HueWave do
@moduledoc """
Creates a wave of shifting hue that moves across the matrix.
"""
alias Chameleon.HSV
alias Layout.LED
alias RGBMatrix.Animation
use Animation
import RGBMatrix.Utils, only: [mod: 2]
defmodule Config do
@moduledoc false
use RGBMatrix.Animation.Config
@doc name: "Speed",
description: """
Controls the speed at which the wave moves across the matrix.
"""
field :speed, :integer, default: 4, min: 0, max: 32
@doc name: "Width",
description: """
The rate of change of the wave, higher values means it's more spread out.
"""
field :width, :integer, default: 20, min: 10, max: 100, step: 10
@doc name: "Direction",
description: """
The direction the wave travels across the matrix.
"""
field :direction, :option,
default: :right,
options: [
:right,
:left,
:up,
:down
]
end
defmodule State do
@moduledoc false
defstruct [:tick, :leds, :steps]
end
@delay_ms 17
@impl true
def new(leds, config) do
steps = 360 / config.width
{0, %State{tick: 0, leds: leds, steps: steps}}
end
@impl true
def render(state, config) do
%{tick: tick, leds: leds, steps: _steps} = state
%{speed: speed, direction: direction} = config
# TODO: fixme
steps = 360 / config.width
time = div(tick * speed, 5)
colors = render_colors(leds, steps, time, direction)
{@delay_ms, colors, %{state | tick: tick + 1}}
end
defp render_colors(leds, steps, time, :right) do
for %LED{id: id, x: x} <- leds do
hue = mod(trunc(x * steps) - time, 360)
{id, HSV.new(hue, 100, 100)}
end
end
defp render_colors(leds, steps, time, :left) do
for %LED{id: id, x: x} <- leds do
hue = mod(trunc(x * steps) + time, 360)
{id, HSV.new(hue, 100, 100)}
end
end
defp render_colors(leds, steps, time, :up) do
for %LED{id: id, y: y} <- leds do
hue = mod(trunc(y * steps) + time, 360)
{id, HSV.new(hue, 100, 100)}
end
end
defp render_colors(leds, steps, time, :down) do
for %LED{id: id, y: y} <- leds do
hue = mod(trunc(y * steps) - time, 360)
{id, HSV.new(hue, 100, 100)}
end
end
@impl true
def interact(state, _config, _led) do
{:ignore, state}
end
end