tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/examples/ft6336/touchpaint/main.go (about) 1 package main 2 3 import ( 4 "image/color" 5 "math" 6 7 "tinygo.org/x/drivers" 8 "tinygo.org/x/drivers/touch" 9 ) 10 11 type touchPaintDisplay interface { 12 drivers.Displayer 13 FillRectangle(x, y, width, height int16, c color.RGBA) error 14 DrawRectangle(x, y, w, h int16, c color.RGBA) error 15 } 16 17 var ( 18 white = color.RGBA{255, 255, 255, 255} 19 black = color.RGBA{0, 0, 0, 255} 20 red = color.RGBA{255, 0, 0, 255} 21 green = color.RGBA{0, 255, 0, 255} 22 blue = color.RGBA{0, 0, 255, 255} 23 magenta = color.RGBA{255, 0, 255, 255} 24 yellow = color.RGBA{255, 255, 0, 255} 25 cyan = color.RGBA{0, 255, 255, 255} 26 27 oldColor color.RGBA 28 currentColor color.RGBA 29 ) 30 31 const ( 32 penRadius = 3 33 boxSize = 30 34 35 Xmin = 0 36 Xmax = 0xFFFF 37 Ymin = 0 38 Ymax = 0xFFFF 39 ) 40 41 func main() { 42 display, resistiveTouch, _ := initDevices() 43 44 // fill the background and activate the backlight 45 width, height := display.Size() 46 display.FillRectangle(0, 0, width, height, black) 47 48 // make color selection boxes 49 display.FillRectangle(0, 0, boxSize, boxSize, red) 50 display.FillRectangle(boxSize, 0, boxSize, boxSize, yellow) 51 display.FillRectangle(boxSize*2, 0, boxSize, boxSize, green) 52 display.FillRectangle(boxSize*3, 0, boxSize, boxSize, cyan) 53 display.FillRectangle(boxSize*4, 0, boxSize, boxSize, blue) 54 display.FillRectangle(boxSize*5, 0, boxSize, boxSize, magenta) 55 display.FillRectangle(boxSize*6, 0, boxSize, boxSize, black) 56 display.FillRectangle(boxSize*7, 0, boxSize, boxSize, white) 57 58 // set the initial color to red and draw a box to highlight it 59 oldColor = red 60 currentColor = red 61 display.DrawRectangle(0, 0, boxSize, boxSize, white) 62 63 last := touch.Point{} 64 65 // loop and poll for touches, including performing debouncing 66 debounce := 0 67 for { 68 69 point := resistiveTouch.ReadTouchPoint() 70 touch := touch.Point{} 71 if point.Z>>6 > 100 { 72 rawX := mapval(point.X, Xmin, Xmax, 0, int(width)) 73 rawY := mapval(point.Y, Ymin, Ymax, 0, int(height)) 74 touch.X = rawX 75 touch.Y = rawY 76 touch.Z = 1 77 } else { 78 touch.X = 0 79 touch.Y = 0 80 touch.Z = 0 81 } 82 83 if last.Z != touch.Z { 84 debounce = 0 85 last = touch 86 } else if math.Abs(float64(touch.X-last.X)) > 4 || 87 math.Abs(float64(touch.Y-last.Y)) > 4 { 88 debounce = 0 89 last = touch 90 } else if debounce > 1 { 91 debounce = 0 92 HandleTouch(display, last) 93 } else if touch.Z > 0 { 94 debounce++ 95 } else { 96 last = touch 97 debounce = 0 98 } 99 100 } 101 } 102 103 // based on Arduino's "map" function 104 func mapval(x int, inMin int, inMax int, outMin int, outMax int) int { 105 return (x-inMin)*(outMax-outMin)/(inMax-inMin) + outMin 106 } 107 108 func HandleTouch(display touchPaintDisplay, touch touch.Point) { 109 110 if int16(touch.Y) < boxSize { 111 oldColor = currentColor 112 x := int16(touch.X) 113 switch { 114 case x < boxSize: 115 currentColor = red 116 case x < boxSize*2: 117 currentColor = yellow 118 case x < boxSize*3: 119 currentColor = green 120 case x < boxSize*4: 121 currentColor = cyan 122 case x < boxSize*5: 123 currentColor = blue 124 case x < boxSize*6: 125 currentColor = magenta 126 case x < boxSize*7: 127 currentColor = black 128 case x < boxSize*8: 129 currentColor = white 130 } 131 132 if oldColor == currentColor { 133 return 134 } 135 136 display.DrawRectangle((x/boxSize)*boxSize, 0, boxSize, boxSize, white) 137 switch oldColor { 138 case red: 139 x = 0 140 case yellow: 141 x = boxSize 142 case green: 143 x = boxSize * 2 144 case cyan: 145 x = boxSize * 3 146 case blue: 147 x = boxSize * 4 148 case magenta: 149 x = boxSize * 5 150 case black: 151 x = boxSize * 6 152 case white: 153 x = boxSize * 7 154 } 155 display.FillRectangle(int16(x), 0, boxSize, boxSize, oldColor) 156 157 } 158 159 if (int16(touch.Y) - penRadius) > boxSize { 160 display.FillRectangle( 161 int16(touch.X), int16(touch.Y), penRadius*2, penRadius*2, currentColor) 162 } 163 }