diff --git a/components/wordclock/wordclock.cpp b/components/wordclock/wordclock.cpp index 848b636..ee41e18 100644 --- a/components/wordclock/wordclock.cpp +++ b/components/wordclock/wordclock.cpp @@ -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 *a_vec, std::vectoradded_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 *a_vec, std::vectorend()) { 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 *elements = this->hours; for (int i = 0; i < elements->size(); i++) { @@ -184,6 +206,7 @@ Wordclock::Wordclock( this->added_segments = new std::vector(); this->removed_segments = new std::vector(); + this->staying_segments = new std::vector(); this->on_transformer = new BrightnessTransitionTransformer(); // this->on_transformer->setup(0, this->brightness, 700); diff --git a/components/wordclock/wordclock.h b/components/wordclock/wordclock.h index 226efc0..6104dfb 100644 --- a/components/wordclock/wordclock.h +++ b/components/wordclock/wordclock.h @@ -164,9 +164,13 @@ protected: std::vector *added_segments; std::vector *removed_segments; + std::vector *staying_segments; + std::vector *current_segments; std::vector *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); diff --git a/susannes_wordclock.yaml b/susannes_wordclock.yaml index e47a2d5..d947563 100644 --- a/susannes_wordclock.yaml +++ b/susannes_wordclock.yaml @@ -48,8 +48,6 @@ light: pin: GPIO3 num_leds: 198 restore_mode: ALWAYS_OFF - # default_transition_length: 0.0s - # default_transition_length: 0.1s method: type: esp8266_dma @@ -77,21 +75,15 @@ display: return (y * 18 + mapping_odd[x]); } -# color: -# - id: col_on -# hex: "CC0000" -# - id: col_off -# hex: "005500" - color: - id: col_on red: 90% green: 50% blue: 0% - id: col_off - red: 20% - green: 20% - blue: 30% + red: 0% + green: 0% + blue: 0% wordclock: time_id: current_time