feat: add rainbow effect for segments
This commit is contained in:
parent
dd1408c5cb
commit
b712b90be1
3 changed files with 93 additions and 25 deletions
|
|
@ -80,23 +80,31 @@ void Wordclock::update() {
|
|||
|
||||
// Color on = this->on_color * this->on_transformer->apply().value_or(255);
|
||||
// Color off = this->off_color * this->off_transformer->apply().value_or(255);
|
||||
this->current_position = 0;
|
||||
uint8_t transition_progress = this->on_transformer->apply().value_or(255);
|
||||
// uint8_t on_progress = this->on_transformer->apply().value_or(255);
|
||||
// uint8_t off_progress = this->off_transformer->apply().value_or(255);
|
||||
// ESP_LOGD("wordclock.cpp", "off progress [%d]", off_progress);
|
||||
Color added_color = this->off_color.gradient(this->on_color, transition_progress);
|
||||
// Color added_color = this->off_color.gradient(this->on_color, transition_progress);
|
||||
Color removed_color = this->on_color.gradient(this->off_color, transition_progress);
|
||||
// ESP_LOGD("wordclock.cpp", "transition progress [%d], added [0x%06x], removed [0x%06x]", transition_progress, added_color.raw_32, removed_color.raw_32);
|
||||
for (uint16_t segment_idx : *this->added_segments) {
|
||||
// ESP_LOGD("wordclock.cpp", "on [%d]", segment_idx);
|
||||
this->draw_segment(segment_idx, added_color);
|
||||
// this->draw_segment(segment_idx, on_progress);
|
||||
}
|
||||
|
||||
for (uint16_t segment_idx : *this->removed_segments) {
|
||||
// ESP_LOGD("wordclock.cpp", "off [%d]", segment_idx);
|
||||
this->draw_segment(segment_idx, removed_color);
|
||||
// this->disable_segment(segment_idx, this->off_color, transition_progress);
|
||||
this->disable_segment_effect(segment_idx, this->off_color, transition_progress);
|
||||
// this->disable_segment(segment_idx, removed_color);
|
||||
// this->draw_segment(segment_idx, off_progress);
|
||||
}
|
||||
for (uint16_t segment_idx : *this->added_segments) {
|
||||
// ESP_LOGD("wordclock.cpp", "on [%d]", segment_idx);
|
||||
// this->segment_effect_base(segment_idx, this->off_color, transition_progress);
|
||||
this->enable_segment_effect(segment_idx, this->off_color, transition_progress);
|
||||
// this->draw_segment(segment_idx, on_progress);
|
||||
}
|
||||
for (uint16_t segment_idx : *this->staying_segments) {
|
||||
this->apply_segment_effect(segment_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,6 +114,8 @@ void Wordclock::find_difference(std::vector<uint16_t> *a_vec, std::vector<uint16
|
|||
// }
|
||||
this->added_segments->clear();
|
||||
this->removed_segments->clear();
|
||||
this->staying_segments->clear();
|
||||
|
||||
|
||||
auto a = a_vec->begin();
|
||||
auto b = b_vec->begin();
|
||||
|
|
@ -115,10 +125,22 @@ void Wordclock::find_difference(std::vector<uint16_t> *a_vec, std::vector<uint16
|
|||
else if (b == b_vec->end()) { this->removed_segments->push_back(*a); a++; }
|
||||
else if (*a > *b) { this->added_segments-> push_back(*b); b++; }
|
||||
else if (*a < *b) { this->removed_segments->push_back(*a); a++; }
|
||||
else if (*a == *b) { a++; b++; }
|
||||
else if (*a == *b) { this->staying_segments->push_back(*a); a++; b++; }
|
||||
}
|
||||
}
|
||||
|
||||
Color Wordclock::get_next_color(uint32_t position, const Color ¤t_color) {
|
||||
uint32_t speed_ = 3;
|
||||
uint16_t width_ = 100;
|
||||
// uint16_t width_ = 50;
|
||||
esphome::light::ESPHSVColor hsv;
|
||||
hsv.value = 255;
|
||||
hsv.saturation = 240;
|
||||
hsv.hue = ((millis() * speed_ + (position * (0xFFFF / width_))) % 0xFFFF) >> 8;
|
||||
// hsv.hue = hue >> 8;
|
||||
return hsv.to_rgb();
|
||||
}
|
||||
|
||||
int8_t Wordclock::find_hour(uint8_t target_value) {
|
||||
std::vector<Hour> *elements = this->hours;
|
||||
for (int i = 0; i < elements->size(); i++) {
|
||||
|
|
@ -184,6 +206,7 @@ Wordclock::Wordclock(
|
|||
|
||||
this->added_segments = new std::vector<uint16_t>();
|
||||
this->removed_segments = new std::vector<uint16_t>();
|
||||
this->staying_segments = new std::vector<uint16_t>();
|
||||
|
||||
this->on_transformer = new BrightnessTransitionTransformer();
|
||||
// this->on_transformer->setup(0, this->brightness, 700);
|
||||
|
|
|
|||
|
|
@ -164,9 +164,13 @@ protected:
|
|||
|
||||
std::vector<uint16_t> *added_segments;
|
||||
std::vector<uint16_t> *removed_segments;
|
||||
std::vector<uint16_t> *staying_segments;
|
||||
|
||||
std::vector<uint16_t> *current_segments;
|
||||
std::vector<uint16_t> *previous_segments;
|
||||
|
||||
uint32_t current_position{0};
|
||||
Color get_next_color(uint32_t position, const Color ¤t_color);
|
||||
// Color
|
||||
// Color get_on_color() {
|
||||
// return this->on_color * this->brightness;
|
||||
|
|
@ -185,14 +189,63 @@ protected:
|
|||
// void draw_segment(uint16_t segment_id) {
|
||||
// this->draw_segment(segment_id, this->brightness);
|
||||
// }
|
||||
void draw_segment(uint16_t segment_id, uint8_t brightness) {
|
||||
this->draw_segment(segment_id, this->on_color * brightness);
|
||||
}
|
||||
void draw_segment(uint16_t segment_id, Color color) {
|
||||
SegmentCoords s = this->segments->at(segment_id);
|
||||
// void draw_segment(uint16_t segment_id, uint8_t brightness) {
|
||||
// this->draw_segment(segment_id, this->on_color * brightness);
|
||||
// }
|
||||
|
||||
// void draw_segment(uint16_t segment_id, Color color) {
|
||||
// SegmentCoords s = this->segments->at(segment_id);
|
||||
// // ESP_LOGD("wordclock.cpp", "brightness[%d] * color[%06x] = %06x", brightness, color.raw_32, (color * brightness).raw_32);
|
||||
// this->display->line(s.x1, s.y1, s.x2, s.y2, color);
|
||||
// }
|
||||
|
||||
void segment_effect_base(uint16_t segment_id, bool to_effect, Color base_color, uint8_t transition_progress) {
|
||||
// ESP_LOGD("wordclock.cpp", "brightness[%d] * color[%06x] = %06x", brightness, color.raw_32, (color * brightness).raw_32);
|
||||
this->display->line(s.x1, s.y1, s.x2, s.y2, color);
|
||||
SegmentCoords s = this->segments->at(segment_id);
|
||||
int x1 = s.x1; int y1 = s.y1; int x2 = s.x2; int y2 = s.y2;
|
||||
Color color_to_draw;
|
||||
Color effect_color;
|
||||
|
||||
const int32_t dx = abs(x2 - x1), sx = x1 < x2 ? 1 : -1;
|
||||
const int32_t dy = -abs(y2 - y1), sy = y1 < y2 ? 1 : -1;
|
||||
int32_t err = dx + dy;
|
||||
while (true) {
|
||||
effect_color = this->get_next_color(x1 + y1, Color(0));
|
||||
if (to_effect) {
|
||||
color_to_draw = base_color.gradient(effect_color, transition_progress);
|
||||
} else {
|
||||
color_to_draw = effect_color.gradient(base_color, transition_progress);
|
||||
// c = base_color.gradient(this->get_next_color(x1 + y1, Color(0)), transition_progress);
|
||||
}
|
||||
|
||||
this->display->draw_pixel_at(x1, y1, color_to_draw);
|
||||
// this->display->draw_pixel_at(x1, y1, this->get_next_color(this->current_position++, Color(0)));
|
||||
if (x1 == x2 && y1 == y2) break;
|
||||
int32_t e2 = 2 * err;
|
||||
if (e2 >= dy) {
|
||||
err += dy;
|
||||
x1 += sx;
|
||||
}
|
||||
if (e2 <= dx) {
|
||||
err += dx;
|
||||
y1 += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void enable_segment_effect(uint16_t segment_id, Color off_color, uint8_t transition_progress) {
|
||||
segment_effect_base(segment_id, true, off_color, transition_progress);
|
||||
}
|
||||
void disable_segment_effect(uint16_t segment_id, Color off_color, uint8_t transition_progress) {
|
||||
segment_effect_base(segment_id, false, off_color, transition_progress);
|
||||
}
|
||||
void apply_segment_effect(uint16_t segment_id) {
|
||||
segment_effect_base(segment_id, true, Color(0), 255);
|
||||
}
|
||||
// void disable_segment(uint16_t segment_id, Color off_color, uint8_t transition_progress) {
|
||||
// SegmentCoords s = this->segments->at(segment_id);
|
||||
// this->display->line(s.x1, s.y1, s.x2, s.y2, color);
|
||||
// }
|
||||
void start_idle_animation() {
|
||||
this->display->fill(this->off_color);
|
||||
this->display->set_enabled(false);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue