feathers.py

../_images/feathers.png

Smoothly scroll rainbow-colored mirrored random curves across the display.

  1"""
  2feathers.py
  3===========
  4
  5.. figure:: /_static/feathers.png
  6  :align: center
  7
  8  Smoothly scroll rainbow-colored mirrored random curves across the display.
  9"""
 10
 11import random
 12import math
 13import utime
 14import gc9a01
 15import tft_config
 16
 17def between(left, right, along):
 18    """returns a point along the curve from left to right"""
 19    dist = (1 - math.cos(along * math.pi)) / 2
 20    return left * (1 - dist) + right * dist
 21
 22
 23def color_wheel(position):
 24    """returns a 565 color from the given position of the color wheel"""
 25    position = (255 - position) % 255
 26
 27    if position < 85:
 28        return gc9a01.color565(255 - position * 3, 0, position * 3)
 29
 30    if position < 170:
 31        position -= 85
 32        return gc9a01.color565(0, position * 3, 255 - position * 3)
 33
 34    position -= 170
 35    return gc9a01.color565(position * 3, 255 - position * 3, 0)
 36
 37
 38def main():
 39    '''
 40    The big show!
 41    '''
 42
 43    tft = tft_config.config(1)  # configure driver to rotate screen 90 degrees
 44    tft.init()                  # initialize display
 45
 46    height = tft.height()       # height of display in pixels
 47    width = tft.width()         # width if display in pixels
 48
 49    tfa = tft_config.TFA	    # top free area when scrolling
 50    bfa = tft_config.BFA	    # bottom free area when scrolling
 51
 52    scroll = 0                  # scroll position
 53    wheel = 0                   # color wheel position
 54
 55    tft.vscrdef(tfa, width, bfa)    # set scroll area
 56    tft.vscsad(scroll + tfa)        # set scroll position
 57    tft.fill(gc9a01.BLACK)          # clear screen
 58
 59    half = (height >> 1) - 1    # half the height of the display
 60    interval = 0                # steps between new points
 61    increment = 0               # increment per step
 62    counter = 1                 # step counter, overflow to start
 63    current_y = 0               # current_y value (right point)
 64    last_y = 0                  # last_y value (left point)
 65
 66    # segment offsets
 67    x_offsets = [x * (width // 8) -1 for x in range(2,9)]
 68
 69    while True:
 70        # when the counter exceeds the interval, save current_y to last_y,
 71        # choose a new random value for current_y between 0 and 1/2 the
 72        # height of the display, choose a new random interval then reset
 73        # the counter to 0
 74
 75        if counter > interval:
 76            last_y = current_y
 77            current_y = random.randint(0, half)
 78            counter = 0
 79            interval = random.randint(10, 100)
 80            increment = 1 / interval
 81
 82        # clear the first column of the display and scroll it
 83        tft.vline(scroll, 0, height, gc9a01.BLACK)
 84        tft.vscsad(scroll + tfa)
 85
 86        # get the next point between last_y and current_y
 87        tween = int(between(last_y, current_y, counter * increment))
 88
 89        # draw mirrored pixels across the display at the offsets using the color_wheel effect
 90        for i, x_offset in enumerate(x_offsets):
 91            tft.pixel((scroll + x_offset) % width, half + tween, color_wheel(wheel+(i<<2)))
 92            tft.pixel((scroll + x_offset) % width, half - tween, color_wheel(wheel+(i<<2)))
 93
 94        # increment scroll, counter, and wheel
 95        scroll = (scroll + 1) % width
 96        wheel = (wheel + 1) % 256
 97        counter += 1
 98
 99        # pause to slow down scrolling
100        utime.sleep(0.005)
101
102
103main()