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()