PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

122 行
3.0KB

  1. #ifndef TRANSITION_SCROLL_H__
  2. #define TRANSITION_SCROLL_H__
  3. #include <Arduino.h>
  4. #include "ILI9341_t3.h"
  5. #include "MathUtil.h"
  6. #include "BaseTransition.h"
  7. const float TRANSITION_SCROLL_SPEED = 0.0014f;
  8. const float SCROLL_WRAPS = 5.0f;
  9. const uint_fast8_t MAX_STAGGER_X = 20;
  10. const uint_fast8_t MAX_STAGGER_HEIGHT = 4;
  11. const float STAGGER_X_STRENGTH = 100.0f; // stagger is higher when the ease motion is faster
  12. class TransitionScroll : public BaseTransition {
  13. public:
  14. TransitionScroll() : BaseTransition() {};
  15. void init( ILI9341_t3 tft );
  16. void restart( ILI9341_t3 tft, uint_fast16_t color );
  17. void perFrame( ILI9341_t3 tft, FrameParams frameParams );
  18. boolean isComplete();
  19. private:
  20. float _phase = 0;
  21. uint_fast16_t _color;
  22. float _lastEase;
  23. uint_fast16_t _lastScroll;
  24. uint16_t * _pixels;
  25. };
  26. void TransitionScroll::init( ILI9341_t3 tft ) {
  27. _pixels = (uint16_t*)malloc( sizeof(uint_fast16_t) * tft.width() );
  28. }
  29. void TransitionScroll::restart( ILI9341_t3 tft, uint_fast16_t inColor ) {
  30. //uint_fast16_t w = tft.width();
  31. //uint_fast16_t h = tft.height();
  32. _phase = 0;
  33. _color = inColor;
  34. _lastEase = 0;
  35. _lastScroll = tft.width();
  36. }
  37. float easeInOutCubic( float p ) {
  38. if( p < 0.5f ) {
  39. float p2 = p * 2.0f;
  40. return (p2*p2*p2) * 0.5f;
  41. }
  42. float p2 = (1.0f - p) * 2.0f;
  43. return 1.0f - (p2*p2*p2) * 0.5f;
  44. }
  45. float easeInOutQuart( float p ) {
  46. if( p < 0.5f ) {
  47. float p2 = p * 2.0f;
  48. return (p2*p2*p2*p2) * 0.5f;
  49. }
  50. float p2 = (1.0f - p) * 2.0f;
  51. return 1.0f - (p2*p2*p2*p2) * 0.5f;
  52. }
  53. void TransitionScroll::perFrame( ILI9341_t3 tft, FrameParams frameParams ) {
  54. uint_fast16_t w = (uint_fast16_t)tft.width();
  55. uint_fast16_t h = (uint_fast16_t)tft.height();
  56. _phase += frameParams.timeMult * TRANSITION_SCROLL_SPEED * SCROLL_WRAPS;
  57. // Apply some easing. Linear speed feels dull
  58. float ease = min( easeInOutCubic( _phase ), 1.0f );
  59. float unwrapped = SCROLL_WRAPS * ease;
  60. float wrap = unwrapped - floor(unwrapped);
  61. // scroll values fall from 1 to 0, so the image appears to move left.
  62. float scroll_f = w * (1.0f - wrap);
  63. uint_fast16_t scroll = floor(scroll_f);
  64. tft.setScroll( scroll );
  65. // Final frame: Fill with destination color
  66. if( unwrapped >= (SCROLL_WRAPS-1.0f) ) {
  67. if( scroll < _lastScroll ) {
  68. tft.fillRect( w - _lastScroll, 0, _lastScroll - scroll, h, _color );
  69. _lastScroll = scroll;
  70. }
  71. // Fill part of a random line
  72. uint_fast16_t x = random((uint_fast16_t)(w*0.9f),w);
  73. uint_fast16_t y = random(h);
  74. tft.drawFastHLine( x, y, w-x, _color );
  75. } else {
  76. // Let's noise this thing up
  77. uint_fast16_t staggerX = 1 + constrain( (ease-_lastEase) * STAGGER_X_STRENGTH, 0.0f, 1.0f ) * MAX_STAGGER_X;
  78. uint_fast8_t staggerHeight = random(1,MAX_STAGGER_HEIGHT+1);
  79. uint_fast16_t startY = random(h-(staggerHeight-1));
  80. for( uint_fast8_t line=0; line<staggerHeight; line++ ) {
  81. uint_fast16_t y = startY + line;
  82. tft.readRect( 0, y, w, 1, _pixels );
  83. tft.writeRect( staggerX, y, w-staggerX, 1, _pixels );
  84. }
  85. }
  86. _lastEase = ease;
  87. }
  88. boolean TransitionScroll::isComplete() {
  89. return _phase >= 1.0f;
  90. }
  91. #endif