canvas

package module
v0.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 30, 2019 License: BSD-3-Clause Imports: 18 Imported by: 34

README

Go canvas GoDoc

Canvas is a pure Go library based on OpenGL that provides drawing functionality as similar as possible to the HTML5 canvas API. It has nothing to do with HTML or Javascript, the functions are just made to be approximately the same.

Many of the basic functions are supported, but it is still a work in progress. The library aims to accept a lot of different parameters on each function in a similar way as the Javascript API does.

Whereas the Javascript API uses a context that all draw calls go to, here all draw calls are directly on the canvas type. The other difference is that here setters are used instead of properties for things like fonts and line width.

The library is intended to provide decent performance. Obviously it will not be able to rival hand coded OpenGL for a given purpose, but for many purposes it will be enough. It can also be combined with hand coded OpenGL.

SDL/GLFW convenience packages

The sdlcanvas and glfwcanvas subpackages provide a very simple way to get started with just a few lines of code. As the names imply they are based on the SDL library and the GLFW library respectively. They create a window for you and give you a canvas to draw with.

OS support

  • Linux
  • Windows
  • macOS
  • Android
  • iOS

Using gomobile to build a full Go app using gomobile build now works by using an offscreen texture to render to and then rendering that to the screen. See the example in examples/gomobile. The offscreen texture is necessary since gomobile automatically creates a GL context without a stencil buffer, which this library requires.

Example

Look at the example/drawing package for some drawing examples.

Here is a simple example for how to get started:

package main

import (
	"math"

	"github.com/tfriedel6/canvas/sdlcanvas"
)

func main() {
	wnd, cv, err := sdlcanvas.CreateWindow(1280, 720, "Hello")
	if err != nil {
		panic(err)
	}
	defer wnd.Destroy()

	wnd.MainLoop(func() {
		w, h := float64(cv.Width()), float64(cv.Height())
		cv.SetFillStyle("#000")
		cv.FillRect(0, 0, w, h)

		for r := 0.0; r < math.Pi*2; r += math.Pi * 0.1 {
			cv.SetFillStyle(int(r*10), int(r*20), int(r*40))
			cv.BeginPath()
			cv.MoveTo(w*0.5, h*0.5)
			cv.Arc(w*0.5, h*0.5, math.Min(w, h)*0.4, r, r+0.1*math.Pi, false)
			cv.ClosePath()
			cv.Fill()
		}

		cv.SetStrokeStyle("#FFF")
		cv.SetLineWidth(10)
		cv.BeginPath()
		cv.Arc(w*0.5, h*0.5, math.Min(w, h)*0.4, 0, math.Pi*2, false)
		cv.Stroke()
	})
}

The result:

Implemented features

These features should work just like their HTML5 counterparts, but there are likely to be a lot of edge cases where they don't work exactly the same way.

  • beginPath
  • closePath
  • moveTo
  • lineTo
  • rect
  • arc
  • arcTo
  • quadraticCurveTo
  • bezierCurveTo
  • stroke
  • fill
  • clip
  • save
  • restore
  • scale
  • translate
  • rotate
  • transform
  • setTransform
  • fillText
  • measureText
  • textAlign
  • textBaseline
  • fillStyle
  • strokeText
  • strokeStyle
  • linear gradients
  • radial gradients
  • image patterns
  • lineWidth
  • lineEnd (square, butt, round)
  • lineJoin (bevel, miter, round)
  • miterLimit
  • lineDash
  • getLineDash
  • lineDashOffset
  • global alpha
  • drawImage
  • getImageData
  • putImageData
  • clearRect
  • shadowColor
  • shadowOffset(X/Y)
  • shadowBlur

Missing features

  • globalCompositeOperation
  • isPointInPath
  • isPointInStroke
  • textBaseline hanging and ideographic (currently work just like top and bottom)
  • full self intersecting polygon support
  • image patterns with repeat and transform

Version history

v0.7.1

  • Line strokes are now scaled and transformed correctly
  • Added an ImagePattern type and a CreatePattern function (still missing repeat and transform)

v0.7.0

  • Restuctured the code to have a single frontend and multiple backends, although currently only Go-GL and an automatically generated xmobile GL backend are available. This should in theory make it possible to write a software backend as well, or maybe Vulkan or some other libraries.

  • Got rid of the OpenGL interface and used Go-GL for Android and iOS. I also tried using it for Shiny and gomobile, but for some reason once the xmobile GL context is created, Go-GL no longer works, so those use the xmobile GL backend.

  • SetLineEnd is now SetLineCap

Documentation

Overview

Package canvas provides an API that tries to closely mirror that of the HTML5 canvas API, using OpenGL to do the rendering.

Index

Constants

View Source
const (
	Miter = iota
	Bevel
	Round
	Square
	Butt
)

Line join and end constants for SetLineJoin and SetLineCap

View Source
const (
	Left = iota
	Center
	Right
	Start
	End
)

Text alignment constants for SetTextAlign

View Source
const (
	Alphabetic = iota
	Top
	Hanging
	Middle
	Ideographic
	Bottom
)

Text baseline constants for SetTextBaseline

Variables

View Source
var Performance = struct {
	IgnoreSelfIntersections bool
	AssumeConvex            bool
}{}

Performance is a nonstandard setting to improve the performance of the rendering in some circumstances. Disabling self intersections will lead to incorrect rendering of self intersecting polygons, but will yield better performance when not using the polygons are not self intersecting. Assuming convex polygons will break concave polygons, but improve performance even further

Functions

This section is empty.

Types

type Canvas

type Canvas struct {
	// contains filtered or unexported fields
}

Canvas represents an area on the viewport on which to draw using a set of functions very similar to the HTML5 canvas

func New

func New(backend backendbase.Backend) *Canvas

New creates a new canvas with the given viewport coordinates. While all functions on the canvas use the top left point as the origin, since GL uses the bottom left coordinate, the coordinates given here also use the bottom left as origin

func (*Canvas) Arc

func (cv *Canvas) Arc(x, y, radius, startAngle, endAngle float64, anticlockwise bool)

Arc adds a circle segment to the end of the path. x/y is the center, radius is the radius, startAngle and endAngle are angles in radians, anticlockwise means that the line is added anticlockwise

func (*Canvas) ArcTo

func (cv *Canvas) ArcTo(x1, y1, x2, y2, radius float64)

ArcTo adds to the current path by drawing a line toward x1/y1 and a circle segment of a radius given by the radius parameter. The circle touches the lines from the end of the path to x1/y1, and from x1/y1 to x2/y2. The line will only go to where the circle segment would touch the latter line

func (*Canvas) BeginPath

func (cv *Canvas) BeginPath()

BeginPath clears the current path and starts a new one

func (*Canvas) BezierCurveTo

func (cv *Canvas) BezierCurveTo(x1, y1, x2, y2, x3, y3 float64)

BezierCurveTo adds a bezier curve to the path. It uses the current end point of the path, x1/y1 and x2/y2 define the curve, and x3/y3 is the end point

func (*Canvas) ClearRect

func (cv *Canvas) ClearRect(x, y, w, h float64)

ClearRect sets the color of the rectangle to transparent black

func (*Canvas) Clip

func (cv *Canvas) Clip()

Clip uses the current path to clip any further drawing. Use Save/Restore to remove the clipping again

func (*Canvas) ClosePath

func (cv *Canvas) ClosePath()

ClosePath closes the path to the beginning of the path or the last point from a MoveTo call

func (*Canvas) CreateLinearGradient added in v0.7.0

func (cv *Canvas) CreateLinearGradient(x0, y0, x1, y1 float64) *LinearGradient

CreateLinearGradient creates a new linear gradient with the coordinates from where to where the gradient will apply on the canvas

func (*Canvas) CreatePattern added in v0.7.1

func (cv *Canvas) CreatePattern(src interface{}, repetition string) *ImagePattern

CreatePattern creates a new image pattern with the specified image and repetition

func (*Canvas) CreateRadialGradient added in v0.7.0

func (cv *Canvas) CreateRadialGradient(x0, y0, r0, x1, y1, r1 float64) *RadialGradient

CreateRadialGradient creates a new radial gradient with the coordinates and the radii for two circles. The gradient will apply from the first to the second circle

func (*Canvas) DrawImage

func (cv *Canvas) DrawImage(image interface{}, coords ...float64)

DrawImage draws the given image to the given coordinates. The image parameter can be an Image loaded by LoadImage, a file name string that will be loaded and cached, or a name string that corresponds to a previously loaded image with the same name parameter.

The coordinates must be one of the following:

DrawImage("image", dx, dy)
DrawImage("image", dx, dy, dw, dh)
DrawImage("image", sx, sy, sw, sh, dx, dy, dw, dh)

Where dx/dy/dw/dh are the destination coordinates and sx/sy/sw/sh are the source coordinates

func (*Canvas) Fill

func (cv *Canvas) Fill()

Fill fills the current path with the current FillStyle

func (*Canvas) FillPath added in v0.7.0

func (cv *Canvas) FillPath(path *Path2D)

FillPath fills the given path with the current FillStyle

func (*Canvas) FillRect

func (cv *Canvas) FillRect(x, y, w, h float64)

FillRect fills a rectangle with the active fill style

func (*Canvas) FillText

func (cv *Canvas) FillText(str string, x, y float64)

FillText draws the given string at the given coordinates using the currently set font and font height

func (*Canvas) GetImageData

func (cv *Canvas) GetImageData(x, y, w, h int) *image.RGBA

GetImageData returns an RGBA image of the current image

func (*Canvas) GetLineDash

func (cv *Canvas) GetLineDash() []float64

GetLineDash gets the line dash style

func (*Canvas) Height

func (cv *Canvas) Height() int

Height returns the internal height of the canvas

func (*Canvas) LineTo

func (cv *Canvas) LineTo(x, y float64)

LineTo adds a line to the end of the path

func (*Canvas) LoadFont added in v0.7.0

func (cv *Canvas) LoadFont(src interface{}) (*Font, error)

LoadFont loads a font and returns the result. The font can be a file name or a byte slice in TTF format

func (*Canvas) LoadImage added in v0.7.0

func (cv *Canvas) LoadImage(src interface{}) (*Image, error)

LoadImage loads an image. The src parameter can be either an image from the standard image package, a byte slice that will be loaded, or a file name string. If you want the canvas package to load the image, make sure you import the required format packages

func (*Canvas) MeasureText

func (cv *Canvas) MeasureText(str string) TextMetrics

MeasureText measures the given string using the current font and font height

func (*Canvas) MoveTo

func (cv *Canvas) MoveTo(x, y float64)

MoveTo adds a gap and moves the end of the path to x/y

func (*Canvas) PutImageData

func (cv *Canvas) PutImageData(img *image.RGBA, x, y int)

PutImageData puts the given image at the given x/y coordinates

func (*Canvas) QuadraticCurveTo

func (cv *Canvas) QuadraticCurveTo(x1, y1, x2, y2 float64)

QuadraticCurveTo adds a quadratic curve to the path. It uses the current end point of the path, x1/y1 defines the curve, and x2/y2 is the end point

func (*Canvas) Rect

func (cv *Canvas) Rect(x, y, w, h float64)

Rect creates a closed rectangle path for stroking or filling

func (*Canvas) Restore

func (cv *Canvas) Restore()

Restore restores the last draw state from the stack if available

func (*Canvas) Rotate

func (cv *Canvas) Rotate(angle float64)

Rotate updates the current transformation with a rotation by the given angle

func (*Canvas) Save

func (cv *Canvas) Save()

Save saves the current draw state to a stack

func (*Canvas) Scale

func (cv *Canvas) Scale(x, y float64)

Scale updates the current transformation with a scaling by the given values

func (*Canvas) SetFillStyle

func (cv *Canvas) SetFillStyle(value ...interface{})

SetFillStyle sets the color, gradient, or image for any fill calls. To set a color, there are several acceptable formats: 3 or 4 int values for RGB(A) in the range 0-255, 3 or 4 float values for RGB(A) in the range 0-1, hex strings in the format "#AABBCC", "#AABBCCDD", "#ABC", or "#ABCD"

func (*Canvas) SetFont

func (cv *Canvas) SetFont(src interface{}, size float64)

SetFont sets the font and font size. The font parameter can be a font loaded with the LoadFont function, a filename for a font to load (which will be cached), or nil, in which case the first loaded font will be used

func (*Canvas) SetGlobalAlpha

func (cv *Canvas) SetGlobalAlpha(alpha float64)

SetGlobalAlpha sets the global alpha value

func (*Canvas) SetLineCap added in v0.7.0

func (cv *Canvas) SetLineCap(cap lineCap)

SetLineCap sets the style of line endings for rendering a path with Stroke The value can be Butt, Square, or Round

func (*Canvas) SetLineDash

func (cv *Canvas) SetLineDash(dash []float64)

SetLineDash sets the line dash style

func (*Canvas) SetLineDashOffset

func (cv *Canvas) SetLineDashOffset(offset float64)

func (*Canvas) SetLineJoin

func (cv *Canvas) SetLineJoin(join lineJoin)

SetLineJoin sets the style of line joints for rendering a path with Stroke. The value can be Miter, Bevel, or Round

func (*Canvas) SetLineWidth

func (cv *Canvas) SetLineWidth(width float64)

SetLineWidth sets the line width for any line drawing calls

func (*Canvas) SetMiterLimit

func (cv *Canvas) SetMiterLimit(limit float64)

SetMiterLimit sets the limit for how far a miter line join can be extend. The fallback is a bevel join

func (*Canvas) SetShadowBlur

func (cv *Canvas) SetShadowBlur(r float64)

SetShadowBlur sets the gaussian blur radius of the shadow (0 for no blur)

func (*Canvas) SetShadowColor

func (cv *Canvas) SetShadowColor(color ...interface{})

SetShadowColor sets the color of the shadow. If it is fully transparent (default) then no shadow is drawn

func (*Canvas) SetShadowOffset

func (cv *Canvas) SetShadowOffset(x, y float64)

SetShadowOffset sets the offset of the shadow

func (*Canvas) SetShadowOffsetX

func (cv *Canvas) SetShadowOffsetX(offset float64)

SetShadowOffsetX sets the x offset of the shadow

func (*Canvas) SetShadowOffsetY

func (cv *Canvas) SetShadowOffsetY(offset float64)

SetShadowOffsetY sets the y offset of the shadow

func (*Canvas) SetStrokeStyle

func (cv *Canvas) SetStrokeStyle(value ...interface{})

SetStrokeStyle sets the color, gradient, or image for any line drawing calls. To set a color, there are several acceptable formats: 3 or 4 int values for RGB(A) in the range 0-255, 3 or 4 float values for RGB(A) in the range 0-1, hex strings in the format "#AABBCC", "#AABBCCDD", "#ABC", or "#ABCD"

func (*Canvas) SetTextAlign

func (cv *Canvas) SetTextAlign(align textAlign)

SetTextAlign sets the text align for any text drawing calls. The value can be Left, Center, Right, Start, or End

func (*Canvas) SetTextBaseline added in v0.6.0

func (cv *Canvas) SetTextBaseline(baseline textBaseline)

SetTextBaseline sets the text baseline for any text drawing calls. The value can be Alphabetic (default), Top, Hanging, Middle, Ideographic, or Bottom

func (*Canvas) SetTransform

func (cv *Canvas) SetTransform(a, b, c, d, e, f float64)

SetTransform replaces the current transformation with the given matrix

func (*Canvas) Size

func (cv *Canvas) Size() (int, int)

Size returns the internal width and height of the canvas

func (*Canvas) Stroke

func (cv *Canvas) Stroke()

Stroke uses the current StrokeStyle to draw the current path

func (*Canvas) StrokePath added in v0.7.0

func (cv *Canvas) StrokePath(path *Path2D)

StrokePath uses the current StrokeStyle to draw the given path

func (*Canvas) StrokeRect

func (cv *Canvas) StrokeRect(x, y, w, h float64)

StrokeRect draws a rectangle using the current stroke style

func (*Canvas) StrokeText

func (cv *Canvas) StrokeText(str string, x, y float64)

StrokeText draws the given string at the given coordinates using the currently set font and font height and using the current stroke style

func (*Canvas) Transform

func (cv *Canvas) Transform(a, b, c, d, e, f float64)

Transform updates the current transformation with the given matrix

func (*Canvas) Translate

func (cv *Canvas) Translate(x, y float64)

Translate updates the current transformation with a translation by the given values

func (*Canvas) Width

func (cv *Canvas) Width() int

Width returns the internal width of the canvas

type Font

type Font struct {
	// contains filtered or unexported fields
}

Font is a loaded font that can be passed to the SetFont method

type Image

type Image struct {
	// contains filtered or unexported fields
}

func (*Image) Delete

func (img *Image) Delete()

Delete deletes the image from memory. Any draw calls with a deleted image will not do anything

func (*Image) Height

func (img *Image) Height() int

Height returns the height of the image

func (*Image) Replace

func (img *Image) Replace(src interface{}) error

Replace replaces the image with the new one

func (*Image) Size

func (img *Image) Size() (int, int)

Size returns the width and height of the image

func (*Image) Width

func (img *Image) Width() int

Width returns the width of the image

type ImagePattern added in v0.7.1

type ImagePattern struct {
	// contains filtered or unexported fields
}

ImagePattern is an image pattern that can be used for any fill call

type LinearGradient

type LinearGradient struct {
	// contains filtered or unexported fields
}

LinearGradient is a gradient with any number of stops and any number of colors. The gradient will be drawn such that each point on the gradient will correspond to a straight line

func (*LinearGradient) AddColorStop

func (lg *LinearGradient) AddColorStop(pos float64, stopColor ...interface{})

AddColorStop adds a color stop to the gradient. The stops don't have to be added in order, they are sorted into the right place

func (*LinearGradient) Delete

func (lg *LinearGradient) Delete()

Delete explicitly deletes the gradient

type Path2D added in v0.7.0

type Path2D struct {
	// contains filtered or unexported fields
}

func NewPath2D added in v0.7.0

func NewPath2D() *Path2D

NewPath2D creates a new Path2D and returns it

func (*Path2D) Arc added in v0.7.0

func (p *Path2D) Arc(x, y, radius, startAngle, endAngle float64, anticlockwise bool)

Arc (see equivalent function on canvas type)

func (*Path2D) ArcTo added in v0.7.0

func (p *Path2D) ArcTo(x1, y1, x2, y2, radius float64)

ArcTo (see equivalent function on canvas type)

func (*Path2D) BezierCurveTo added in v0.7.0

func (p *Path2D) BezierCurveTo(x1, y1, x2, y2, x3, y3 float64)

BezierCurveTo (see equivalent function on canvas type)

func (*Path2D) ClosePath added in v0.7.0

func (p *Path2D) ClosePath()

ClosePath (see equivalent function on canvas type)

func (*Path2D) LineTo added in v0.7.0

func (p *Path2D) LineTo(x, y float64)

LineTo (see equivalent function on canvas type)

func (*Path2D) MoveTo added in v0.7.0

func (p *Path2D) MoveTo(x, y float64)

MoveTo (see equivalent function on canvas type)

func (*Path2D) QuadraticCurveTo added in v0.7.0

func (p *Path2D) QuadraticCurveTo(x1, y1, x2, y2 float64)

QuadraticCurveTo (see equivalent function on canvas type)

func (*Path2D) Rect added in v0.7.0

func (p *Path2D) Rect(x, y, w, h float64)

Rect (see equivalent function on canvas type)

type RadialGradient

type RadialGradient struct {
	// contains filtered or unexported fields
}

RadialGradient is a gradient with any number of stops and any number of colors. The gradient will be drawn such that each point on the gradient will correspond to a circle

func (*RadialGradient) AddColorStop

func (rg *RadialGradient) AddColorStop(pos float64, stopColor ...interface{})

AddColorStop adds a color stop to the gradient. The stops don't have to be added in order, they are sorted into the right place

func (*RadialGradient) Delete

func (rg *RadialGradient) Delete()

Delete explicitly deletes the gradient

type TextMetrics

type TextMetrics struct {
	Width                    float64
	ActualBoundingBoxAscent  float64
	ActualBoundingBoxDescent float64
}

TextMetrics is the result of a MeasureText call

Directories

Path Synopsis
backend
gogl/gl
Package gl implements Go bindings to OpenGL.
Package gl implements Go bindings to OpenGL.
examples
ios
sdl

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL