-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathpct.go
294 lines (251 loc) · 10 KB
/
pct.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
package giocanvas
import (
"image"
"image/color"
"math"
"gioui.org/text"
)
// Methods using percentage-based, (x and y range from 0-100),
// classical coordinate system (x increasing left to right, y increasing bottom to top)
// Lines and shapes
// Line makes a stroked line using percentage-based measures
// from (x0, y0) to (x1, y1), stroke width size
func (c *Canvas) Line(x0, y0, x1, y1, size float32, strokecolor color.NRGBA) {
x0, y0 = dimen(x0, y0, c.Width, c.Height)
x1, y1 = dimen(x1, y1, c.Width, c.Height)
size = pct(size, c.Width)
c.AbsLine(x0, y0, x1, y1, size, strokecolor)
}
// VLine makes a vertical line beginning at (x,y) with dimension (w, h)
// the line begins at (x,y) and moves upward by linewidth
func (c *Canvas) VLine(x, y, lineheight, size float32, linecolor color.NRGBA) {
c.Line(x, y, x, y+lineheight, size, linecolor)
}
// HLine makes a horizontal line starting at (x, y), with dimensions (w, h)
// the line begin at (x,y) and extends to the left by linewidth
func (c *Canvas) HLine(x, y, linewidth, size float32, linecolor color.NRGBA) {
c.Line(x, y, x+linewidth, y, size, linecolor)
}
// Polygon makes a filled polygon using percentage-based measures
// vertices in x and y,
func (c *Canvas) Polygon(x, y []float32, fillcolor color.NRGBA) {
if len(x) != len(y) || len(x) < 3 {
return
}
nx := make([]float32, len(x))
ny := make([]float32, len(y))
for i := 0; i < len(x); i++ {
nx[i], ny[i] = dimen(x[i], y[i], c.Width, c.Height)
}
c.AbsPolygon(nx, ny, fillcolor)
}
// QuadCurve makes a filled quadradic Bezier curve, using percentage-based measures
// starting at (x, y), control point at (cx, cy), end point (ex, ey)
func (c *Canvas) QuadCurve(x, y, cx, cy, ex, ey float32, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
cx, cy = dimen(cx, cy, c.Width, c.Height)
ex, ey = dimen(ex, ey, c.Width, c.Height)
c.AbsQuadBezier(x, y, cx, cy, ex, ey, 0, fillcolor)
}
// Curve makes a filled quadradic Bezier curve, using percentage-based measures
// starting at (x, y), control point at (cx, cy), end point (ex, ey)
func (c *Canvas) Curve(x, y, cx, cy, ex, ey float32, fillcolor color.NRGBA) {
c.QuadCurve(x, y, cx, cy, ex, ey, fillcolor)
}
// QuadStrokedCurve makes a stroked quadradic Bezier curve, using percentage-based measures
// starting at (x, y), control point at (cx, cy), end point (ex, ey)
func (c *Canvas) QuadStrokedCurve(x, y, cx, cy, ex, ey, size float32, strokecolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
cx, cy = dimen(cx, cy, c.Width, c.Height)
ex, ey = dimen(ex, ey, c.Width, c.Height)
size = pct(size, c.Width)
c.AbsStrokedQuadBezier(x, y, cx, cy, ex, ey, size, strokecolor)
}
// StrokedCurve makes a stroked quadradic bezier curve
func (c *Canvas) StrokedCurve(x, y, cx, cy, ex, ey, size float32, fillcolor color.NRGBA) {
c.QuadStrokedCurve(x, y, cx, cy, ex, ey, size, fillcolor)
}
// CubeCurve makes a cubic Bezier curve, using percentage-based measures
// starting at (x, y), control points at (cx1, cy1), (cx2, cy2), end point (ex, ey)
func (c *Canvas) CubeCurve(x, y, cx1, cy1, cx2, cy2, ex, ey float32, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
cx1, cy1 = dimen(cx1, cy1, c.Width, c.Height)
cx2, cy2 = dimen(cx2, cy2, c.Width, c.Height)
ex, ey = dimen(ex, ey, c.Width, c.Height)
c.AbsCubicBezier(x, y, cx1, cy1, cx2, cy2, ex, ey, 0, fillcolor)
}
func (c *Canvas) CubeStrokedCurve(x, y, cx1, cy1, cx2, cy2, ex, ey, size float32, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
cx1, cy1 = dimen(cx1, cy1, c.Width, c.Height)
cx2, cy2 = dimen(cx2, cy2, c.Width, c.Height)
ex, ey = dimen(ex, ey, c.Width, c.Height)
size = pct(size, c.Width)
c.AbsStrokedCubicBezier(x, y, cx1, cy1, cx2, cy2, ex, ey, size, fillcolor)
}
// StrokedCubeCurve makes a stroked cubic bezier curve
func (c *Canvas) StrokedCubeCurve(x, y, cx1, cy1, cx2, cy2, ex, ey, size float32, strokecolor color.NRGBA) {
c.CubeStrokedCurve(x, y, cx1, cy1, cx2, cy2, ex, ey, size, strokecolor)
}
// Circle makes a filled circle, using percentage-based measures
// center is (x,y), radius r
func (c *Canvas) Circle(x, y, r float32, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
r = pct(r, c.Width)
c.AbsCircle(x, y, r, fillcolor)
}
// Ellipse makes a filled circle, using percentage-based measures
// center is (x,y), radii (w, h)
func (c *Canvas) Ellipse(x, y, w, h float32, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
w = pct(w, c.Width)
h = pct(h, c.Height)
c.AbsEllipse(x, y, w, h, fillcolor)
}
// Arc makes a filled arc, using percentage-based measures
// center is (x, y) the arc begins at angle a1, and ends at a2, with radius r.
// The arc is filled with the specified color.
func (c *Canvas) Arc(x, y, r float32, a1, a2 float64, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
pr := pct(r, c.Width)
c.AbsArc(x, y, pr, a1, a2, fillcolor)
}
// ArcLine makes a stroked arc, using percentage-based measures
// center is (x, y), the arc begins at angle a1, and ends at a2, with radius r.
// The arc is stroked with the specified stroke size and color
func (c *Canvas) ArcLine(x, y, r float32, a1, a2 float64, size float32, fillcolor color.NRGBA) {
/*
step := (a2 - a1) / 100
x1, y1 := c.Polar(x, y, r, float32(a1))
for t := a1 + step; t <= a2; t += step {
x2, y2 := c.Polar(x, y, r, float32(t))
c.Line(x1, y1, x2, y2, size, fillcolor)
x1 = x2
y1 = y2
}
*/
// Define minimum and maximum step sizes
const minstep = 0.001
const maxstep = 0.1
const twoPi = math.Pi * 2
// Ensure the angles are in the range [0, 2π)
a1 = math.Mod(a1, twoPi)
a2 = math.Mod(a2, twoPi)
// Calculate step size based on the radius (Smaller steps for larger radius)
step := float64(1.0 / (3.0 * r * twoPi))
// Clamp step to be within the defined range for performance reasons
if step < minstep {
step = minstep
}
if step > maxstep {
step = maxstep
}
// Ensure we handle crossing the 0/2π boundary correctly
if a2 < a1 {
a2 += twoPi
}
// Initialize the starting point
x1, y1 := c.Polar(x, y, r, float32(a1))
for t := a1; t < a2; t += step {
x2, y2 := c.Polar(x, y, r, float32(t))
c.Line(x1, y1, x2, y2, size, fillcolor)
x1 = x2
y1 = y2
}
}
// Text methods
// Text places text using percentage-based measures
// left at x, baseline at y, at the specified size and color
func (c *Canvas) Text(x, y, size float32, s string, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
size = pct(size, c.Width)
c.textops(x, y, size, text.Start, s, fillcolor)
}
// TextEnd places text using percentage-based measures
// x is the end of the string, baseline at y, using specified size and color
func (c *Canvas) TextEnd(x, y, size float32, s string, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
size = pct(size, c.Width)
c.textops(x, y, size, text.End, s, fillcolor)
}
// TextMid places text using percentage-based measures
// text is centered at x, baseline y, using specied size and color
func (c *Canvas) TextMid(x, y, size float32, s string, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
size = pct(size, c.Width)
c.textops(x, y, size, text.Middle, s, fillcolor)
}
// EText - alternative name for TextEnd
func (c *Canvas) EText(x, y, size float32, s string, fillcolor color.NRGBA) {
c.TextEnd(x, y, size, s, fillcolor)
}
// CText - alternative name for TextMid
func (c *Canvas) CText(x, y, size float32, s string, fillcolor color.NRGBA) {
c.TextMid(x, y, size, s, fillcolor)
}
// TextWrap places and wraps text using percentage-based measures
// text begins at (x,y), baseline y, and wraps at width, using specied size and color
func (c *Canvas) TextWrap(x, y, size, width float32, s string, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
size = pct(size, c.Width)
width = pct(width, c.Width)
c.AbsTextWrap(x, y, size, width, s, fillcolor)
}
// Rect makes a rectangle using percentage-based measures
// upper left corner at (x,y), with size at (w,h)
func (c *Canvas) Rect(x, y, w, h float32, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
w = pct(w, c.Width)
h = pct(h, c.Height)
c.AbsCenterRect(x, y, w, h, fillcolor)
}
// CornerRect makes a rectangle using percentage-based measures
// upper left corner at (x,y), with sized at (w,h)
func (c *Canvas) CornerRect(x, y, w, h float32, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
w = pct(w, c.Width)
h = pct(h, c.Height)
c.AbsRect(x, y, w, h, fillcolor)
}
// Square makes a square shape, using percentage based measures
// centered at (x, y), sides are w. Accounts for screen aspect
func (c *Canvas) Square(x, y, w float32, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
w = pct(w, c.Height)
h := pct(100, w)
c.AbsCenterRect(x, y, w, h, fillcolor)
}
// CenterRect makes a rectangle using percentage-based measures
// with center at (x,y), sized at (w,h)
func (c *Canvas) CenterRect(x, y, w, h float32, fillcolor color.NRGBA) {
x, y = dimen(x, y, c.Width, c.Height)
w = pct(w, c.Width)
h = pct(h, c.Height)
c.AbsCenterRect(x, y, w, h, fillcolor)
}
// Images
// Img places a scaled image centered at (x, y), data from image.Image
// using percentage coordinates and scales
func (c *Canvas) Img(im image.Image, x, y float32, w, h int, scale float32) {
x, y = dimen(x, y, c.Width, c.Height)
c.AbsImg(im, x, y, w, h, scale)
}
// Image places a scaled image centered at (x,y), reading from a named file,
// using percetage coordinates and scales
func (c *Canvas) Image(name string, x, y float32, w, h int, scale float32) {
c.CenterImage(name, x, y, w, h, scale)
}
// CenterImage places a scaled image centered at (x,y),
// using percentage coordinates and scales
func (c *Canvas) CenterImage(name string, x, y float32, w, h int, scale float32) {
x, y = dimen(x, y, c.Width, c.Height)
c.AbsCenterImage(name, x, y, w, h, scale)
}
// pct returns the percentage of its input
func pct(p float32, m float32) float32 {
return ((p / 100.0) * m)
}
// dimen returns canvas dimensions from percentages
// (converting from x increasing left-right, y increasing top-bottom)
func dimen(xp, yp, w, h float32) (float32, float32) {
return pct(xp, w), pct(100-yp, h)
}