Last active
May 25, 2020 15:50
-
-
Save ajstarks/e02c70e74ab57a622d9ccb2e3351d6a0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"flag" | |
"fmt" | |
"image" | |
"image/color" | |
_ "image/gif" | |
_ "image/jpeg" | |
_ "image/png" | |
"math/rand" | |
"os" | |
"gioui.org/app" | |
"gioui.org/f32" | |
"gioui.org/font/gofont" | |
"gioui.org/io/system" | |
"gioui.org/layout" | |
"gioui.org/op" | |
"gioui.org/op/paint" | |
"gioui.org/text" | |
"gioui.org/unit" | |
"gioui.org/widget/material" | |
) | |
var textColor = color.RGBA{0, 0, 0, 255} | |
// Canvas defines the Gio canvas | |
type Canvas struct { | |
Width, Height float32 | |
TextColor color.RGBA | |
Context *layout.Context | |
} | |
// NewCanvas initializes a Canvas | |
func NewCanvas(width, height float32) *Canvas { | |
canvas := new(Canvas) | |
canvas.Width = width | |
canvas.Height = height | |
canvas.TextColor = color.RGBA{0, 0, 0, 255} | |
canvas.Context = new(layout.Context) | |
return canvas | |
} | |
// Text places text at (x,y) | |
func (c *Canvas) Text(x, y, size float32, s string, color color.RGBA) { | |
var stack op.StackOp | |
th := material.NewTheme() | |
stack.Push(c.Context.Ops) | |
op.TransformOp{}.Offset(f32.Point{X: x, Y: y}).Add(c.Context.Ops) | |
l := material.Label(th, unit.Dp(size), s) | |
l.Color = color | |
l.Alignment = text.Start | |
l.Layout(c.Context) | |
stack.Pop() | |
} | |
// TextMid places text centered at (x,y) | |
func (c *Canvas) TextMid(x, y, size float32, s string, color color.RGBA) { | |
var stack op.StackOp | |
th := material.NewTheme() | |
stack.Push(c.Context.Ops) | |
op.TransformOp{}.Offset(f32.Point{X: x - c.Width/2, Y: y}).Add(c.Context.Ops) | |
l := material.Label(th, unit.Dp(size), s) | |
l.Color = color | |
l.Alignment = text.Middle | |
l.Layout(c.Context) | |
stack.Pop() | |
} | |
// TextEnd places text aligned to the end | |
func (c *Canvas) TextEnd(x, y, size float32, s string, color color.RGBA) { | |
var stack op.StackOp | |
th := material.NewTheme() | |
stack.Push(c.Context.Ops) | |
op.TransformOp{}.Offset(f32.Point{X: x - c.Width, Y: y}).Add(c.Context.Ops) | |
l := material.Label(th, unit.Dp(size), s) | |
l.Color = color | |
l.Alignment = text.End | |
l.Layout(c.Context) | |
stack.Pop() | |
} | |
// Rect makes a filled Rectangle; left corner at (x, y), with dimensions (w,h) | |
func (c *Canvas) Rect(x, y, w, h float32, color color.RGBA) { | |
ops := c.Context.Ops | |
r := f32.Rect(x, y+h, x+w, y) | |
paint.ColorOp{Color: color}.Add(ops) | |
paint.PaintOp{Rect: r}.Add(ops) | |
} | |
// CenterRect makes a filled rectangle centered at (x, y), with dimensions (w,h) | |
func (c *Canvas) CenterRect(x, y, w, h float32, color color.RGBA) { | |
ops := c.Context.Ops | |
r := f32.Rect(x-(w/2), y+(h/2), x+(w/2), y-(h/2)) | |
paint.ColorOp{Color: color}.Add(ops) | |
paint.PaintOp{Rect: r}.Add(ops) | |
} | |
// VLine makes a vertical line beginning at (x,y) with dimension (w, h) | |
// half of the width is left of x, the other half is the to right of x | |
func (c *Canvas) VLine(x, y, w, h float32, color color.RGBA) { | |
c.Rect(x-(w/2), y, w, h, color) | |
} | |
// HLine makes a horizontal line starting at (x, y), with dimensions (w, h) | |
// half of the height is above y, the other below | |
func (c *Canvas) HLine(x, y, w, h float32, color color.RGBA) { | |
c.Rect(x, y-(h/2), w, h, color) | |
} | |
// randrect randomly places random sized rectangles | |
func (c *Canvas) randrect(w, h float32, n int) { | |
color := color.RGBA{R: 0, G: 0, B: 0, A: 255} | |
for i := 0; i < n; i++ { | |
x := rand.Float32() * w | |
y := rand.Float32() * h | |
w := rand.Float32() * 100 | |
h := rand.Float32() * 100 | |
color.R = uint8(rand.Intn(255)) | |
color.G = uint8(rand.Intn(255)) | |
color.B = uint8(rand.Intn(255)) | |
color.A = uint8(rand.Intn(255)) | |
c.CenterRect(x, y, w, h, color) | |
} | |
} | |
// Grid uses horizontal and vertical lines to make a grid | |
func (c *Canvas) Grid(width, height, size, interval float32, color color.RGBA) { | |
var x, y float32 | |
for y = 0; y <= height; y += height / interval { | |
c.HLine(0, y, width, size, color) | |
} | |
for x = 0; x <= width; x += width / interval { | |
c.VLine(x, 0, size, height, color) | |
} | |
} | |
// CenterImage places a named image centered at (x, y) | |
// scaled using the specified dimensions (w, h) | |
func (c *Canvas) CenterImage(name string, x, y float32, w, h int, scale float32) { | |
r, err := os.Open(name) | |
if err != nil { | |
fmt.Fprintf(os.Stderr, "%v\n", err) | |
return | |
} | |
im, _, err := image.Decode(r) | |
if err != nil { | |
fmt.Fprintf(os.Stderr, "%v\n", err) | |
return | |
} | |
// compute scaled image dimensions | |
// if w and h are zero, use the natural dimensions | |
sc := scale / 100 | |
imw := float32(w) * sc | |
imh := float32(h) * sc | |
if w == 0 && h == 0 { | |
b := im.Bounds() | |
imw = float32(b.Max.X) * sc | |
imh = float32(b.Max.Y) * sc | |
} | |
// center the image | |
x = x - (imw / 2) | |
y = y - (imh / 2) | |
ops := c.Context.Ops | |
paint.NewImageOp(im).Add(ops) | |
paint.PaintOp{Rect: f32.Rect(x, y, x+imw, y+imh)}.Add(ops) | |
} | |
func (c *Canvas) fade(y, width, size, interval float32, fint uint8, color color.RGBA) { | |
for x := float32(0); x <= width; x += width / interval { | |
c.CenterRect(x, y, size, size, color) | |
c.TextMid(x, y+10, size, fmt.Sprintf("%v", color.A), c.TextColor) | |
color.A -= fint | |
} | |
} | |
func main() { | |
var w, h int | |
flag.IntVar(&w, "width", 1200, "canvas width") | |
flag.IntVar(&h, "height", 900, "canvas height") | |
flag.Parse() | |
width := float32(w) | |
height := float32(h) | |
size := app.Size(unit.Dp(width), unit.Dp(height)) | |
title := app.Title("2D API Test") | |
gofont.Register() | |
tcolor := color.RGBA{128, 0, 0, 255} | |
gcolor := color.RGBA{0, 0, 0, 128} | |
fcolor := color.RGBA{0, 0, 128, 255} | |
go func() { | |
w := app.NewWindow(title, size) | |
canvas := NewCanvas(width, height) | |
for e := range w.Events() { | |
if e, ok := e.(system.FrameEvent); ok { | |
canvas.Context.Reset(e.Queue, e.Config, e.Size) | |
canvas.Text(width*0.60, height*0.55, 40, "Follow your dreams", tcolor) | |
canvas.Text(width*0.10, height*0.55, 40, "Random", tcolor) | |
canvas.CenterImage("follow.jpg", width*0.75, height*0.25, 816, 612, 75) | |
canvas.randrect(width/2, height/2, 300) | |
canvas.Grid(width, height, 2, 20, gcolor) | |
canvas.fade(height*0.75, width, 20, 20, 10, fcolor) | |
for x := float32(0); x <= canvas.Width; x += canvas.Width / 20 { | |
v := fmt.Sprintf("%v", x) | |
canvas.Text(x, height*0.80, 15, v, tcolor) | |
canvas.TextMid(x, height*0.85, 15, v, tcolor) | |
canvas.TextEnd(x, height*0.90, 15, v, tcolor) | |
} | |
e.Frame(canvas.Context.Ops) | |
} | |
} | |
}() | |
app.Main() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment