PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.8KB

  1. #ifndef TRANSITION_HALFTONE_H__
  2. #define TRANSITION_HALFTONE_H__
  3. #include <Arduino.h>
  4. #include "ILI9341_t3.h"
  5. #include "MathUtil.h"
  6. #include "BaseTransition.h"
  7. const float HALFTONE_SPEED = 0.06f;
  8. const float HALFTONE_SLOPE = 0.5f;
  9. const int_fast8_t HALFTONE_CIRC_SIZE = 15;
  10. const uint_fast8_t HALFTONE_CIRC_SPACING = (uint_fast8_t)(HALFTONE_CIRC_SIZE * cos(M_PI/6.0f)) * 2 - 1;
  11. class TransitionHalftone : public BaseTransition {
  12. public:
  13. TransitionHalftone() : BaseTransition() {};
  14. void init( ILI9341_t3 tft );
  15. void restart( ILI9341_t3 tft, uint_fast16_t color );
  16. void perFrame( ILI9341_t3 tft, FrameParams frameParams );
  17. boolean isComplete();
  18. private:
  19. float _phase = 0;
  20. uint_fast16_t _color;
  21. boolean _isComplete = false;
  22. };
  23. void TransitionHalftone::init( ILI9341_t3 tft ) {
  24. }
  25. void TransitionHalftone::restart( ILI9341_t3 tft, uint_fast16_t inColor ) {
  26. //uint_fast16_t w = tft.width();
  27. //uint_fast16_t h = tft.height();
  28. _phase = 0;
  29. _color = inColor;
  30. _isComplete = false;
  31. }
  32. void TransitionHalftone::perFrame( ILI9341_t3 tft, FrameParams frameParams ) {
  33. uint_fast16_t w = (uint_fast16_t)tft.width();
  34. uint_fast16_t h = (uint_fast16_t)tft.height();
  35. uint_fast16_t w_2 = (w>>1);
  36. uint_fast16_t h_2 = (h>>1);
  37. float _prevPhase = _phase;
  38. _phase += frameParams.timeMult * HALFTONE_SPEED;
  39. boolean anySmallCircles = false;
  40. // Draw circes, offset so circles grow out from center
  41. int_fast8_t across = (w / (HALFTONE_CIRC_SPACING*cos(M_PI/6.0f))) + 1;
  42. int_fast8_t across_2 = (across>>1);
  43. int_fast8_t down = h / HALFTONE_CIRC_SPACING + 1;
  44. int_fast8_t down_2 = (down>>1)+1;
  45. for( int_fast8_t i=-across_2; i<=across_2; i++ ) {
  46. for( int_fast8_t j=-down_2; j<=down_2; j++ ) {
  47. float i_f = (float)(i);
  48. float j_f = (float)(j);
  49. if( i & 0x1 ) j_f -= 0.5f; // Stagger odd columns, so a triangular lattice is formed
  50. float distance = sqrtf( i_f*i_f + j_f*j_f );
  51. int_fast8_t prevSize = HALFTONE_CIRC_SIZE * constrain( _prevPhase - distance*HALFTONE_SLOPE, 0.0f, 1.0f );
  52. int_fast8_t size = HALFTONE_CIRC_SIZE * constrain( _phase - distance*HALFTONE_SLOPE, 0.0f, 1.0f );
  53. if( size < HALFTONE_CIRC_SIZE ) anySmallCircles = true;
  54. // Only redraw circles that change size
  55. if( size > prevSize ) {
  56. int_fast16_t x = w_2 + i_f*HALFTONE_CIRC_SPACING;
  57. int_fast16_t y = h_2 + j_f*HALFTONE_CIRC_SPACING;
  58. tft.fillCircle( x, y, size, _color );
  59. // Circle drawing issue: Circles at the top of the screen aren't filling correctly,
  60. // so just draw a box there :P
  61. if( j == -down_2 ) {
  62. tft.fillRect( max( x-size, 0 ), max( y-size, 0 ), size*2, size*2, _color );
  63. }
  64. }
  65. }
  66. }
  67. // When all circles are full-size, the transition is done!
  68. _isComplete = !anySmallCircles;
  69. }
  70. boolean TransitionHalftone::isComplete() {
  71. return _isComplete;
  72. }
  73. #endif