Top Related Projects
Cross platform GUI toolkit in Go inspired by Material Design
Ebitengine - A dead simple 2D game engine for Go
A pure Go game engine
Qt binding for Go (Golang) with support for Windows / macOS / Linux / FreeBSD / Android / iOS / Sailfish OS / Raspberry Pi / AsteroidOS / Ubuntu Touch / JavaScript / WebAssembly
Quick Overview
gg is a 2D graphics library for Go. It provides a simple and efficient way to create vector graphics, render text, and generate images. The library is designed to be easy to use while offering powerful features for creating complex graphics.
Pros
- Simple and intuitive API for 2D graphics
- High-quality anti-aliasing and subpixel rendering
- Support for various output formats (PNG, SVG, PDF)
- Efficient performance for rendering complex graphics
Cons
- Limited to 2D graphics (no 3D support)
- Fewer advanced features compared to some larger graphics libraries
- Primarily focused on static graphics, not interactive or animated content
Code Examples
Drawing a circle:
dc := gg.NewContext(1000, 1000)
dc.DrawCircle(500, 500, 400)
dc.SetRGB(0, 0, 0)
dc.Fill()
dc.SavePNG("circle.png")
Drawing text with a custom font:
dc := gg.NewContext(1000, 1000)
if err := dc.LoadFontFace("path/to/font.ttf", 72); err != nil {
panic(err)
}
dc.SetRGB(0, 0, 0)
dc.DrawString("Hello, World!", 100, 500)
dc.SavePNG("text.png")
Creating a gradient:
dc := gg.NewContext(1000, 1000)
grad := gg.NewLinearGradient(0, 0, 1000, 1000)
grad.AddColorStop(0, color.RGBA{255, 0, 0, 255})
grad.AddColorStop(1, color.RGBA{0, 0, 255, 255})
dc.SetFillStyle(grad)
dc.DrawRectangle(0, 0, 1000, 1000)
dc.Fill()
dc.SavePNG("gradient.png")
Getting Started
To use gg in your Go project, first install it:
go get -u github.com/fogleman/gg
Then, import it in your Go code:
import "github.com/fogleman/gg"
Here's a simple example to create a blank canvas and save it as a PNG:
package main
import "github.com/fogleman/gg"
func main() {
dc := gg.NewContext(1000, 1000)
dc.SetRGB(1, 1, 1)
dc.Clear()
dc.SavePNG("blank.png")
}
Competitor Comparisons
Cross platform GUI toolkit in Go inspired by Material Design
Pros of Fyne
- Cross-platform GUI toolkit for desktop, mobile, and web applications
- Rich set of pre-built widgets and layouts for rapid development
- Active community and regular updates
Cons of Fyne
- Steeper learning curve for developers new to GUI programming
- Limited customization options for widget appearance
Code Comparison
Fyne example:
package main
import (
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/widget"
)
func main() {
myApp := app.New()
myWindow := myApp.NewWindow("Hello")
myWindow.SetContent(widget.NewLabel("Hello Fyne!"))
myWindow.ShowAndRun()
}
gg example:
package main
import "github.com/fogleman/gg"
func main() {
dc := gg.NewContext(1000, 1000)
dc.DrawCircle(500, 500, 400)
dc.SetRGB(0, 0, 0)
dc.Fill()
dc.SavePNG("out.png")
}
Summary
Fyne is a comprehensive GUI toolkit for building cross-platform applications, while gg focuses on 2D graphics rendering. Fyne offers a wide range of pre-built widgets and layouts, making it suitable for complex GUI applications. gg, on the other hand, provides a simpler API for creating 2D graphics and images. The choice between the two depends on the specific requirements of your project.
Ebitengine - A dead simple 2D game engine for Go
Pros of Ebiten
- Focused on game development with built-in game loop and input handling
- Cross-platform support, including mobile and web browsers
- Active development and community support
Cons of Ebiten
- Steeper learning curve for non-game applications
- Less flexibility for general-purpose graphics tasks
- Limited built-in drawing primitives compared to GG
Code Comparison
gg example:
dc := gg.NewContext(1000, 1000)
dc.DrawCircle(500, 500, 400)
dc.SetRGB(0, 0, 0)
dc.Fill()
dc.SavePNG("output.png")
Ebiten example:
type Game struct{}
func (g *Game) Update() error {
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
ebitenutil.DrawCircle(screen, 500, 500, 400, color.Black)
}
func (g *Game) Layout(w, h int) (int, int) {
return 1000, 1000
}
GG is more straightforward for simple drawing tasks, while Ebiten requires a game structure but offers more game-specific features. GG is better suited for static image generation, whereas Ebiten excels in interactive applications and games.
A pure Go game engine
Pros of Oak
- More comprehensive game development framework with built-in scene management and entity-component system
- Active development and community support, with regular updates and contributions
- Includes audio support and collision detection out of the box
Cons of Oak
- Steeper learning curve due to more complex architecture and features
- Potentially overkill for simple 2D graphics projects
- Less flexible for non-game graphics applications
Code Comparison
Oak example:
type player struct {
oak.Entity
}
func (p *player) Init() {
p.SetDimensions(32, 32)
p.SetPosition(100, 100)
}
oak.Add("main", func(string, interface{}) {
oak.SetViewportBounds(0, 0, 800, 600)
oak.Add("main", &player{})
})
GG example:
dc := gg.NewContext(1000, 1000)
dc.DrawCircle(500, 500, 400)
dc.SetRGB(0, 0, 0)
dc.Fill()
dc.SavePNG("out.png")
Oak is more suited for game development with its entity-based approach, while GG focuses on simple 2D drawing operations. Oak provides a structured framework for game logic, while GG offers a straightforward API for creating graphics. The choice between them depends on the project's complexity and requirements.
Qt binding for Go (Golang) with support for Windows / macOS / Linux / FreeBSD / Android / iOS / Sailfish OS / Raspberry Pi / AsteroidOS / Ubuntu Touch / JavaScript / WebAssembly
Pros of Qt
- Comprehensive GUI framework with extensive widget library
- Cross-platform support for desktop and mobile applications
- Large and active community with extensive documentation
Cons of Qt
- Steeper learning curve due to its complexity
- Larger binary sizes and potential performance overhead
- Licensing considerations for commercial applications
Code Comparison
Qt example:
package main
import (
"os"
"github.com/therecipe/qt/widgets"
)
func main() {
app := widgets.NewQApplication(len(os.Args), os.Args)
window := widgets.NewQMainWindow(nil, 0)
window.SetWindowTitle("Hello World")
window.Show()
app.Exec()
}
gg example:
package main
import "github.com/fogleman/gg"
func main() {
dc := gg.NewContext(1000, 1000)
dc.DrawCircle(500, 500, 400)
dc.SetRGB(0, 0, 0)
dc.Fill()
dc.SavePNG("output.png")
}
Summary
Qt offers a comprehensive GUI framework with cross-platform support, while gg focuses on 2D graphics rendering. Qt provides a rich set of widgets and tools for building complex applications, but comes with a steeper learning curve and larger overhead. gg, on the other hand, offers a simpler API for 2D graphics operations, making it more suitable for specific graphics-related tasks rather than full-fledged GUI applications.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Go Graphics
gg
is a library for rendering 2D graphics in pure Go.
Installation
go get -u github.com/fogleman/gg
Alternatively, you may use gopkg.in to grab a specific major-version:
go get -u gopkg.in/fogleman/gg.v1
Documentation
- godoc: https://godoc.org/github.com/fogleman/gg
- pkg.go.dev: https://pkg.go.dev/github.com/fogleman/gg?tab=doc
Hello, Circle!
Look how easy!
package main
import "github.com/fogleman/gg"
func main() {
dc := gg.NewContext(1000, 1000)
dc.DrawCircle(500, 500, 400)
dc.SetRGB(0, 0, 0)
dc.Fill()
dc.SavePNG("out.png")
}
Examples
There are lots of examples included. They're mostly for testing the code, but they're good for learning, too.
Creating Contexts
There are a few ways of creating a context.
NewContext(width, height int) *Context
NewContextForImage(im image.Image) *Context
NewContextForRGBA(im *image.RGBA) *Context
Drawing Functions
Ever used a graphics library that didn't have functions for drawing rectangles or circles? What a pain!
DrawPoint(x, y, r float64)
DrawLine(x1, y1, x2, y2 float64)
DrawRectangle(x, y, w, h float64)
DrawRoundedRectangle(x, y, w, h, r float64)
DrawCircle(x, y, r float64)
DrawArc(x, y, r, angle1, angle2 float64)
DrawEllipse(x, y, rx, ry float64)
DrawEllipticalArc(x, y, rx, ry, angle1, angle2 float64)
DrawRegularPolygon(n int, x, y, r, rotation float64)
DrawImage(im image.Image, x, y int)
DrawImageAnchored(im image.Image, x, y int, ax, ay float64)
SetPixel(x, y int)
MoveTo(x, y float64)
LineTo(x, y float64)
QuadraticTo(x1, y1, x2, y2 float64)
CubicTo(x1, y1, x2, y2, x3, y3 float64)
ClosePath()
ClearPath()
NewSubPath()
Clear()
Stroke()
Fill()
StrokePreserve()
FillPreserve()
It is often desired to center an image at a point. Use DrawImageAnchored
with ax
and ay
set to 0.5 to do this. Use 0 to left or top align. Use 1 to right or bottom align. DrawStringAnchored
does the same for text, so you don't need to call MeasureString
yourself.
Text Functions
It will even do word wrap for you!
DrawString(s string, x, y float64)
DrawStringAnchored(s string, x, y, ax, ay float64)
DrawStringWrapped(s string, x, y, ax, ay, width, lineSpacing float64, align Align)
MeasureString(s string) (w, h float64)
MeasureMultilineString(s string, lineSpacing float64) (w, h float64)
WordWrap(s string, w float64) []string
SetFontFace(fontFace font.Face)
LoadFontFace(path string, points float64) error
Color Functions
Colors can be set in several different ways for your convenience.
SetRGB(r, g, b float64)
SetRGBA(r, g, b, a float64)
SetRGB255(r, g, b int)
SetRGBA255(r, g, b, a int)
SetColor(c color.Color)
SetHexColor(x string)
Stroke & Fill Options
SetLineWidth(lineWidth float64)
SetLineCap(lineCap LineCap)
SetLineJoin(lineJoin LineJoin)
SetDash(dashes ...float64)
SetDashOffset(offset float64)
SetFillRule(fillRule FillRule)
Gradients & Patterns
gg
supports linear, radial and conic gradients and surface patterns. You can also implement your own patterns.
SetFillStyle(pattern Pattern)
SetStrokeStyle(pattern Pattern)
NewSolidPattern(color color.Color)
NewLinearGradient(x0, y0, x1, y1 float64)
NewRadialGradient(x0, y0, r0, x1, y1, r1 float64)
NewConicGradient(cx, cy, deg float64)
NewSurfacePattern(im image.Image, op RepeatOp)
Transformation Functions
Identity()
Translate(x, y float64)
Scale(x, y float64)
Rotate(angle float64)
Shear(x, y float64)
ScaleAbout(sx, sy, x, y float64)
RotateAbout(angle, x, y float64)
ShearAbout(sx, sy, x, y float64)
TransformPoint(x, y float64) (tx, ty float64)
InvertY()
It is often desired to rotate or scale about a point that is not the origin. The functions RotateAbout
, ScaleAbout
, ShearAbout
are provided as a convenience.
InvertY
is provided in case Y should increase from bottom to top vs. the default top to bottom.
Stack Functions
Save and restore the state of the context. These can be nested.
Push()
Pop()
Clipping Functions
Use clipping regions to restrict drawing operations to an area that you defined using paths.
Clip()
ClipPreserve()
ResetClip()
AsMask() *image.Alpha
SetMask(mask *image.Alpha)
InvertMask()
Helper Functions
Sometimes you just don't want to write these yourself.
Radians(degrees float64) float64
Degrees(radians float64) float64
LoadImage(path string) (image.Image, error)
LoadPNG(path string) (image.Image, error)
SavePNG(path string, im image.Image) error
Another Example
See the output of this example below.
package main
import "github.com/fogleman/gg"
func main() {
const S = 1024
dc := gg.NewContext(S, S)
dc.SetRGBA(0, 0, 0, 0.1)
for i := 0; i < 360; i += 15 {
dc.Push()
dc.RotateAbout(gg.Radians(float64(i)), S/2, S/2)
dc.DrawEllipse(S/2, S/2, S*7/16, S/8)
dc.Fill()
dc.Pop()
}
dc.SavePNG("out.png")
}
Top Related Projects
Cross platform GUI toolkit in Go inspired by Material Design
Ebitengine - A dead simple 2D game engine for Go
A pure Go game engine
Qt binding for Go (Golang) with support for Windows / macOS / Linux / FreeBSD / Android / iOS / Sailfish OS / Raspberry Pi / AsteroidOS / Ubuntu Touch / JavaScript / WebAssembly
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot