Skip to content

Instantly share code, notes, and snippets.

@ajstarks
Last active May 25, 2020 15:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ajstarks/e02c70e74ab57a622d9ccb2e3351d6a0 to your computer and use it in GitHub Desktop.
Save ajstarks/e02c70e74ab57a622d9ccb2e3351d6a0 to your computer and use it in GitHub Desktop.
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