-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFadeUtils.h
194 lines (167 loc) · 5.16 KB
/
FadeUtils.h
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
//
// utility to work with colors while adusting brightness and organizing into groups
//
class ColorPalette {
CRGB entries[4];
int num_entries;
int intensity;
void updateColors() {
cBlack = CRGB(0, 0, 0);
cWarmWhite = CRGB(intensity, intensity / 1.2, intensity / 3.4);
cWhite = CRGB(intensity, intensity, intensity);
cGreen = CRGB(0, intensity, 0);
cRed = CRGB(intensity, 0, 0);
cBlue = CRGB(0, 0, intensity);
}
public:
static const int MIN_BRIGHTNESS = 25;
static const int MAX_BRIGHTNESS = 210;
static const int DEFAULT_INTENSITY = 45;
CRGB cBlack;
CRGB cWarmWhite;
CRGB cWhite;
CRGB cGreen;
CRGB cRed;
CRGB cBlue;
ColorPalette (int intensity = DEFAULT_INTENSITY) {
num_entries = 0;
this->intensity = intensity;
updateColors();
}
static CRGB adjustColor(CRGB color, float intensity) {
CRGB rval = CRGB(
min(255,max(0,(float)color.r * intensity)),
min(255,max(0,(float)color.g * intensity)),
min(255,max(0,(float)color.b * intensity)));
return rval;
}
int getIntensity() {
return intensity;
}
void clearPalette() {
num_entries = 0;
}
void addColor(CRGB val) {
float perc = (float)(intensity / 255.0) * 2;
CRGB newcol = CRGB(val.r * perc, val.g * perc, val.b * perc);
entries[num_entries++] = newcol;
}
CRGB getRandom() {
return entries[random(num_entries)];
}
void increaseBrightness() {
if (intensity < MAX_BRIGHTNESS) intensity += 5;
updateColors();
}
void decreaseBrightness() {
if (intensity > MIN_BRIGHTNESS) intensity -= 5;
updateColors();
}
};
//
// utility to slowly fade to a color
//
class FadeUtils {
public:
static bool fadeTo(CRGB* leds, int index, CRGB target, int increment) {
bool fade_completed= true;
if (leds[index].r < target.r - increment) {
leds[index].r+= increment;
fade_completed = false;
} else if (leds[index].r > target.r + increment) {
leds[index].r-= increment;
fade_completed = false;
} else {
leds[index].r = target.r;
}
if (leds[index].g < target.g - increment) {
leds[index].g+= increment;
fade_completed = false;
} else if (leds[index].g > target.g + increment) {
leds[index].g-= increment;
fade_completed = false;
} else {
leds[index].g = target.g;
}
if (leds[index].b < target.b - increment) {
leds[index].b+= increment;
fade_completed = false;
} else if (leds[index].b > target.b + increment) {
leds[index].b-= increment;
fade_completed = false;
} else {
leds[index].b = target.b;
}
return fade_completed;
}
static bool fadeAllTo(CRGB* leds, int num_leds, CRGB target, int increment) {
bool done = true;
for(int idx=0; idx< num_leds; idx++) {
if(!fadeTo(leds, idx, target, increment)) {
done = false;
}
}
return done;
}
};
class Flicker {
bool blink_phase = false;
bool returning_to_start = false;
float cur_intensity = -1;
void updateIntensity( float begin_intensity, float end_intensity, float intensity_increment) {
if (end_intensity < begin_intensity) {
cur_intensity = cur_intensity - intensity_increment;
} else {
cur_intensity = cur_intensity + intensity_increment;
}
if (cur_intensity > max(begin_intensity, end_intensity)) {
cur_intensity = max(begin_intensity, end_intensity);
}
if (cur_intensity < min(begin_intensity, end_intensity)) {
cur_intensity = min(begin_intensity, end_intensity);
}
}
public:
float getIntensity() {
return cur_intensity;
}
//
// fade one LED up or down between two brightness levels while alternating with black to produce a flicker effect
//
bool flicker(int start_position, int end_position, CRGB leds[], float start_intensity, float target_intensity, float flick_down_intensity, bool do_return_to_start,
CRGB base_colors[], float intensity_increment, int num_leds) {
float begin_intensity = start_intensity;
float end_intensity = target_intensity;
if (cur_intensity < 0) {
// begin flicker
cur_intensity = begin_intensity;
returning_to_start = false;
}
// if returning, swap start and target
if (returning_to_start) {
begin_intensity = target_intensity;
end_intensity = start_intensity;
}
if (blink_phase) {
for (int index = start_position; index <= end_position; index++) {
leds[index] = ColorPalette::adjustColor(base_colors[index], flick_down_intensity);
}
} else {
for (int index = start_position; index <= end_position; index++) {
leds[index] = ColorPalette::adjustColor(base_colors[index], cur_intensity);
}
updateIntensity(begin_intensity, end_intensity, intensity_increment);
if (cur_intensity == end_intensity) {
if (do_return_to_start && !returning_to_start) {
returning_to_start = true;
} else {
// done flickering
cur_intensity = -1;
}
}
}
// alternate to and from blinking phase
blink_phase = !blink_phase;
return cur_intensity == -1;
}
};