""" feathers.py =========== .. figure:: ../_static/feathers.jpg :align: center Test hardware scrolling. Smoothly scrolls mirrored rainbow colored random curves across the display. .. note:: This example requires the following modules: .. hlist:: :columns: 3 - `st7789py` - `tft_config` """ import random import math import time import st7789py as st7789 import tft_config def between(left, right, along): """returns a point along the curve from left to right""" dist = (1 - math.cos(along * math.pi)) / 2 return left * (1 - dist) + right * dist def color_wheel(position): """returns a 565 color from the given position of the color wheel""" position = (255 - position) % 255 if position < 85: return st7789.color565(255 - position * 3, 0, position * 3) if position < 170: position -= 85 return st7789.color565(0, position * 3, 255 - position * 3) position -= 170 return st7789.color565(position * 3, 255 - position * 3, 0) def main(): ''' The big show! ''' #enable display and clear screen tft = tft_config.config(tft_config.FEATHERS) height = tft.height # height of display in pixels width = tft.width # width if display in pixels tfa = tft_config.TFA # top free area when scrolling bfa = tft_config.BFA # bottom free area when scrolling scroll = 0 # scroll position wheel = 0 # color wheel position tft.vscrdef(tfa, width, bfa) # set scroll area tft.vscsad(scroll + tfa) # set scroll position tft.fill(st7789.BLACK) # clear screen half = (height >> 1) - 1 # half the height of the dislay interval = 0 # steps between new points increment = 0 # increment per step counter = 1 # step counter, overflow to start current_y = 0 # current_y value (right point) last_y = 0 # last_y value (left point) # segment offsets x_offsets = [x * (width // 8) -1 for x in range(2,9)] while True: # when the counter exceeds the interval, save current_y to last_y, # choose a new random value for current_y between 0 and 1/2 the # height of the display, choose a new random interval then reset # the counter to 0 if counter > interval: last_y = current_y current_y = random.randint(0, half) counter = 0 interval = random.randint(10, 100) increment = 1/interval # increment per step # clear the first column of the display and scroll it tft.vline(scroll, 0, height, st7789.BLACK) tft.vscsad(scroll + tfa) # get the next point between last_y and current_y tween = int(between(last_y, current_y, counter * increment)) # draw mirrored pixels across the display at the offsets using the color_wheel effect for i, x_offset in enumerate(x_offsets): tft.pixel((scroll + x_offset) % width, half + tween, color_wheel(wheel+(i<<2))) tft.pixel((scroll + x_offset) % width, half - tween, color_wheel(wheel+(i<<2))) # increment scroll, counter, and wheel scroll = (scroll + 1) % width wheel = (wheel + 1) % 256 counter += 1 main()