canvas

package
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: Apr 15, 2024 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

The canvas package provides an API for drawing.

It is designed with SVG generation in mind, so the way it describes most operations are derived from the way SVG describes those same operations.

The basic usage looks like:

c := canvas.NewCanvas()
// Add objects to the canvas
r := canvas.NewSVGRenderer(os.Stdout)
c.Render(r)

See the documentation for specific types for more information.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ColorEqual

func ColorEqual(a, b Color) bool

Compare two colors for equality. This will convert the colors to the same space if necessary to do the comparison

a = RGB(0, 0, 0)
b = HSL(0, 0, 0)
ColorEqual(a, b) // true

func RenderChildren

func RenderChildren(renderer Renderer, children []Object) error

Helper function for rendering children

func UnmarshalColorStruct

func UnmarshalColorStruct(data []byte, val any) error

Helper function for decoding structs that contain Color interfaces. Not intended for external use.

Types

type AABB

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

An axis-aligned bounding box

The zero value is a zero-sized bounding box around the origin

func GetCombinedAABB

func GetCombinedAABB(objs []Object) *AABB

Helper function for calculating the union of the AABBs of a set of objects

func NewAABB

func NewAABB(min, max vec.Vec2) *AABB

Constructs a new axis-aligned bounding box from the two points.

func (*AABB) Bounds

func (a *AABB) Bounds() (min, max vec.Vec2)

func (*AABB) Size

func (a *AABB) Size() vec.Vec2

func (*AABB) Transform

func (a *AABB) Transform(t *vec.Transform) *AABB

Transform returns the AABB of a transformed by t

func (*AABB) Union

func (a *AABB) Union(b *AABB) *AABB

Union returns the union of the two AABBs

type Attributes

type Attributes struct {
	Id      string
	Style   *Style
	Classes []string
	Extra   map[string]any
}

Attributes for canvas objects

func (*Attributes) AddClass

func (a *Attributes) AddClass(class string)

AddClass adds the given class to Classes

func (*Attributes) EnsureStyle

func (a *Attributes) EnsureStyle()

EnsureStyle ensures that a.Style is not nil

func (*Attributes) RemoveClass

func (a *Attributes) RemoveClass(class string)

RemoveClass removes the given class from Classes.

If the class isn't in Classes, it does nothing

func (*Attributes) SetExtra

func (a *Attributes) SetExtra(name string, val any)

type Canvas

type Canvas struct {
	Element
	Margin     vec.Vec2 // Specifies the margin around the image
	Stylesheet Stylesheet
}

A Canvas represents an abstract surface to draw to

func NewCanvas

func NewCanvas() *Canvas

NewCanvas returns a new Canvas to draw to

func (*Canvas) GetAABB

func (c *Canvas) GetAABB() *AABB

Returns the axis aligned bounding box of the image

func (*Canvas) Render

func (c *Canvas) Render(renderer Renderer) error

Render the canvas using the given renderer

type Color

type Color interface {
	Space() ColorSpace
	ToRGB() *RGBColor
	ToHSL() *HSLColor
}

Represents an abstract color.

func ParseColor

func ParseColor(s string) (Color, error)

Parse the given string into a Color.

Currently only hex-strings starting with '#' are supported

type ColorParseError

type ColorParseError struct {
	Input string
	Err   error
}

func (*ColorParseError) Error

func (e *ColorParseError) Error() string

func (*ColorParseError) Unwrap

func (e *ColorParseError) Unwrap() error

type ColorScale

type ColorScale struct {
	Space ColorSpace
	// contains filtered or unexported fields
}

func ColorScaleFromMap

func ColorScaleFromMap(m map[float32]Color) *ColorScale

func HeatColorScale

func HeatColorScale() *ColorScale

func NewColorScale

func NewColorScale() *ColorScale

func (*ColorScale) AddColor

func (s *ColorScale) AddColor(val float32, color Color)

func (*ColorScale) GetColor

func (s *ColorScale) GetColor(val float32) Color

func (*ColorScale) MarshalJSON

func (s *ColorScale) MarshalJSON() ([]byte, error)

func (*ColorScale) UnmarshalJSON

func (s *ColorScale) UnmarshalJSON(data []byte) error

type ColorSpace

type ColorSpace int
const (
	ColorSpaceRGB ColorSpace = iota
	ColorSpaceHSL
)

func (ColorSpace) MarshalJSON

func (sp ColorSpace) MarshalJSON() ([]byte, error)

func (ColorSpace) String

func (sp ColorSpace) String() string

func (*ColorSpace) UnmarshalJSON

func (sp *ColorSpace) UnmarshalJSON(data []byte) error

type Command

type Command struct {
	Type CommandType
	Pos  vec.Vec2
	Args []float32
}

Represents a command to draw the path, which may be a path segment.

The content of Args depends the command:

  • `ClosePath`: No args
  • `MoveTo`: [pos.X, pos.Y], the position to move to
  • `LineTo`: [pos.X, pos.Y], the position to draw a line to
  • `ArcTo`: [start.X, start.Y, end.X, end.Y, radius, sweepDir] start is where the arc starts, end is where the arc ends radius is the radius of the circle that the arc is of, sweepDir is the direction the arc is drawn in, 1 for clockwise, 0 for counterclockwise

type CommandType

type CommandType int
const (
	CommandClosePath CommandType = iota
	CommandMoveTo
	CommandLineTo
	CommandArcTo
)

type Container

type Container interface {
	Object
	AppendChild(Object)
}

type Element

type Element struct {
	Attributes Attributes
	Children   []Object
}

Element holds common fields for [Object]s

func (*Element) AppendChild

func (e *Element) AppendChild(obj Object)

func (*Element) GetAttributes

func (e *Element) GetAttributes() *Attributes

type Ellipse

type Ellipse struct {
	Element
	Center vec.Vec2
	Rx     float32
	Ry     float32
}

Ellipse is an ellipse centered at Center with x and y radiuses of Rx and Ry.

func NewCircle

func NewCircle(center vec.Vec2, radius float32) *Ellipse

func NewEllipse

func NewEllipse(center vec.Vec2, rx, ry float32) *Ellipse

func (*Ellipse) GetAABB

func (e *Ellipse) GetAABB() *AABB

func (*Ellipse) Render

func (ellipse *Ellipse) Render(r Renderer) error

type Group

type Group struct {
	Element
	Transform *vec.Transform
}

A group of objects Can also have a transformation applied to it

func NewGroup

func NewGroup() *Group

func (*Group) GetAABB

func (g *Group) GetAABB() *AABB

func (*Group) Render

func (g *Group) Render(r Renderer) error

type HSLColor

type HSLColor struct {
	H float32 // Hue as an angle, valid range is [0, 360)
	S float32 // Saturation, valid range is [0, 1]
	L float32 // Lightness, valid range is [0, 1]
}

Represents a color in the HSL color space.

The HSL color space represents colors using hue, saturation and lightness values

func HSL

func HSL(h, s, l float32) *HSLColor

Constructs a color in the HSL color space.

Hue values outside [0, 360) are adjusted to fall in the range Saturation and lightness values outside of [0, 1] are clamped to that range

func ParseHSLColor

func ParseHSLColor(str string) (*HSLColor, error)

ParseHSLColor parses the given string and returns an HSLColor

The accepted formats are:

hsl(hue, sat, light)
hsl(hue, satPC, lightPC)

Where *hue* is a number between 0 and 360, *sat* and *light* are numbers between 0 and 1, and *satPC* and *lightPC* are percentage values written as "<val>%"

Values outside of the valid ranges will be truncated or normalized as in HSL

func (*HSLColor) Equal

func (a *HSLColor) Equal(b *HSLColor) bool

Returns whether two points in HSL color space represent the same color.

func (*HSLColor) Interpolate

func (a *HSLColor) Interpolate(b *HSLColor, t float32) *HSLColor

Returns the result of doing a component-wise interpolation between x and y, using the interpolation variable t. t is expected to be between 0 and 1, values outside that range are clamped. As the hue represents an angle, there are two lines between any two values with different hues. This function will interpolate along the shorter of the two lines. If the hues are 180 degrees apart, the interpolation will avoid crossing zero.

Example
a := canvas.HSL(60, 0.9, 0.4)
b := canvas.HSL(120, 0.9, 0.6)

mid := a.Interpolate(b, 0.5)
fmt.Println(mid)

a = canvas.HSL(90, 1.0, 0.5)
b = canvas.HSL(270, 1.0, 0.5)

// Returns a hue of 180 instead of 0
mid = a.Interpolate(b, 0.5)
fmt.Println(mid)
Output:

hsl(90, 90%, 50%)
hsl(180, 100%, 50%)

func (*HSLColor) Space

func (hsl *HSLColor) Space() ColorSpace

func (*HSLColor) String

func (hsl *HSLColor) String() string

func (*HSLColor) ToHSL

func (hsl *HSLColor) ToHSL() *HSLColor

Implements the Color interface

Returns the reciever

func (*HSLColor) ToRGB

func (hsl *HSLColor) ToRGB() *RGBColor

Implements the Color interface

Returns the equivalent color in RGB color space

type Line

type Line struct {
	Element
	Start vec.Vec2
	End   vec.Vec2
}

Line is a straight line segment from Start to End

func NewLine

func NewLine(start, end vec.Vec2) *Line

func (*Line) GetAABB

func (l *Line) GetAABB() *AABB

func (*Line) Render

func (line *Line) Render(r Renderer) error

type Object

type Object interface {
	GetAABB() *AABB
	GetAttributes() *Attributes
	Render(Renderer) error
}

Object is the interface implemented by Canvas objects

type Path

type Path struct {
	Element
	Data []Command
}

Path is a generic path through space. It can be either a line itself of the outline of another shape.

func NewPath

func NewPath() *Path

func (*Path) Arc

func (p *Path) Arc(start, end vec.Vec2, radius float32) *Path

func (*Path) ArcNeg

func (p *Path) ArcNeg(start, end vec.Vec2, radius float32) *Path

func (*Path) ClosePath

func (p *Path) ClosePath() *Path

func (*Path) GetAABB

func (p *Path) GetAABB() *AABB

func (*Path) LineTo

func (p *Path) LineTo(pos vec.Vec2) *Path

func (*Path) MoveTo

func (p *Path) MoveTo(pos vec.Vec2) *Path

func (*Path) Render

func (p *Path) Render(r Renderer) error

func (*Path) RoundCorner

func (p *Path) RoundCorner(radius float32, start, peak, end vec.Vec2) *Path

Generates a rounded corner defined by start, end and peak with the radius

type Polygon

type Polygon struct {
	Element
	Points []vec.Vec2
}

Polygon is a closed shape with only straight sides

func NewPolygon

func NewPolygon(points []vec.Vec2) *Polygon

func NewRegularPolygon

func NewRegularPolygon(center vec.Vec2, radius float32, numSides int, sideTop bool) *Polygon

Makes a regular polygon with the given number of sides.

The polygon has vertices the given radius away from the center. Setting `sideTop` to true rotates the polygon such that it has a side at the top, setting it to false means that there is always a point at the top of the polygon

Panics if numSides is less than 3

func (*Polygon) GetAABB

func (p *Polygon) GetAABB() *AABB

func (*Polygon) Render

func (Polygon *Polygon) Render(r Renderer) error

type RGBColor

type RGBColor struct {
	R, G, B float32
}

Represents a color in RGB space using three values from the interval [0, 1]

func ParseHexColor

func ParseHexColor(s string) (*RGBColor, error)

Parse a hex-encoded string, with an optional leading '#', into an RGBColor.

The string must use two bytes per value

func RGB

func RGB(r, g, b float32) *RGBColor

Constructs an RGBColor value, with the given values. values are expected to be between 0 and 1. Values outside that range are clamped to within 0 and 1

func RGBInt

func RGBInt(r, g, b int) *RGBColor

Constructs an RGBColor from 3 integer component values. This is equivalent to calling RGB as:

RGB(r/255, g/255, b/255)

func (*RGBColor) Interpolate

func (x *RGBColor) Interpolate(y *RGBColor, t float32) *RGBColor

Returns the result of doing a component-wise interpolation between x and y, using the interpolation variable t. t is expected to be between 0 and 1, values outside that range are clamped

func (*RGBColor) MarshalText

func (rgb *RGBColor) MarshalText() ([]byte, error)

Implement encoding/TextMarshaler

func (*RGBColor) Space

func (rgb *RGBColor) Space() ColorSpace

func (*RGBColor) String

func (rgb *RGBColor) String() string

func (*RGBColor) ToHSL

func (rgb *RGBColor) ToHSL() *HSLColor

Implement the Color interface

Returns the color in the HSL color space

func (*RGBColor) ToHex

func (rgb *RGBColor) ToHex() string

Returns the color as an hex-encoded string with a leading '#'

func (*RGBColor) ToRGB

func (rgb *RGBColor) ToRGB() *RGBColor

Implement the Color interface, returns the receiver

func (*RGBColor) UnmarshalText

func (rgb *RGBColor) UnmarshalText(text []byte) error

Implement encoding/TextUnmarshaler. Marshals using RGBColor.ToHex

type Rect

type Rect struct {
	Element
	Pos    vec.Vec2
	Width  float32
	Height float32
	Rx     float32
	Ry     float32
}

Rect is a rectangle with optionally rounded corners

func NewRect

func NewRect(pos vec.Vec2, width, height float32) *Rect

func NewSquare

func NewSquare(pos vec.Vec2, width float32) *Rect

func (*Rect) GetAABB

func (r *Rect) GetAABB() *AABB

func (*Rect) Render

func (rect *Rect) Render(r Renderer) error

type Renderer

type Renderer interface {
	RenderCanvas(*Canvas) error
	RenderGroup(*Group) error
	RenderRect(*Rect) error
	RenderEllipse(*Ellipse) error
	RenderLine(*Line) error
	RenderPolygon(*Polygon) error
	RenderPath(*Path) error
	RenderText(*Text) error
}

Renderer is an interface for Canvas renderers. It implements the Visitor pattern

type Rule

type Rule struct {
	Selector Selector
	Style    *Style
}

An individual rule in a stylesheet

type SVGRenderer

type SVGRenderer struct {
	Indent        int  // Controls the size of the indent
	Width         int  // The width of the image, <= 0 means automatic
	Height        int  // The height of the image, <= 0 means automatic
	IncludeHeader bool // Include an XML header, set to false if embedding the file in another document
	IncludeSize   bool
	StyleMode     SVGStyleMode // Mode to use for rendering styles, defaults to SVGStyleNone
	Precision     int          // Controls the precision used for printing floats
	// contains filtered or unexported fields
}

Renders a canvas to a SVG format

The size of the image is determined by the width and height of the canvas and the Width and Height fields.

func NewSVGRenderer

func NewSVGRenderer(f io.Writer) *SVGRenderer

NewSVGRenderer returns a new renderer that writes an SVG to f

func (*SVGRenderer) RenderCDATA added in v0.1.3

func (r *SVGRenderer) RenderCDATA(data string) error

Renders a string as a CDATA element

func (*SVGRenderer) RenderCanvas

func (r *SVGRenderer) RenderCanvas(canvas *Canvas) error

func (*SVGRenderer) RenderComment added in v0.1.3

func (r *SVGRenderer) RenderComment(text string) error

Renders a string inside an XML comment

func (*SVGRenderer) RenderElement added in v0.1.3

func (r *SVGRenderer) RenderElement(name string, attrs map[string]any, children []Object, style *Style) error

Renders an arbitrary element to the document

func (*SVGRenderer) RenderEllipse

func (r *SVGRenderer) RenderEllipse(ellipse *Ellipse) error

RenderEllipse renders an Ellipse object to either an `<ellipse>` elements or a `<circle>` element

func (*SVGRenderer) RenderGroup

func (r *SVGRenderer) RenderGroup(group *Group) error

RenderGroup renders a Group object to a `<g>` element

func (*SVGRenderer) RenderLine

func (r *SVGRenderer) RenderLine(line *Line) error

RenderLine renders a Line object to a `<line>` element

func (*SVGRenderer) RenderPath

func (r *SVGRenderer) RenderPath(path *Path) error

RenderPath renders a Path object to a `<path>` object

func (*SVGRenderer) RenderPolygon

func (r *SVGRenderer) RenderPolygon(polygon *Polygon) error

RenderPolygon renders a Polygon object to a `<polygon>` element

func (*SVGRenderer) RenderRect

func (r *SVGRenderer) RenderRect(rect *Rect) error

RenderRect renders a Rect object to a `<rect>` element

func (*SVGRenderer) RenderText

func (r *SVGRenderer) RenderText(text *Text) error

RenderText renders a Text object to a `<text>` element

type SVGStyleMode

type SVGStyleMode int

Controls the way styles are rendered

const (
	// Don't use stylesheets at all
	SVGStyleNone SVGStyleMode = iota
	// Render an embedded stylesheet into the SVG document
	SVGStyleInternal
	// Include element styles, but don't embed a stylesheet
	// into the document, relying instead on an external
	// stylesheet
	SVGStyleExternal
)

type Selector

type Selector []string

The selection rule that matches classes to styles.

func (Selector) Matches

func (s Selector) Matches(classes []string) bool

Matches returns true if this selector matches the given classes

type Style

type Style struct {
	// The overall opacity of the object
	Opacity option.Float32 `json:"opacity,omitempty"`

	// The color used to fill the object
	FillColor StyleColor `json:"fill,omitempty"`
	// The opacity of the fill
	FillOpacity option.Float32 `json:"fill-opacity,omitempty"`
	// The color used to paint the stroke/outline of the object
	StrokeColor StyleColor `json:"stroke,omitempty"`
	// The opacity of the stroke/outline
	StrokeOpacity option.Float32 `json:"stroke-opacity,omitempty"`
	// The width of the stroke/outline
	StrokeWidth option.Float32 `json:"stroke-width,omitempty"`

	// The font family used for text
	FontFamily string `json:"font-family,omitempty"`
}

Stores style information for an element

func NewStyle

func NewStyle() *Style

func (*Style) Changed

func (s *Style) Changed(other *Style) *Style

Return a style with only the values that have changed from s to other

func (*Style) MarshalJSON

func (s *Style) MarshalJSON() ([]byte, error)

func (*Style) Merge

func (s *Style) Merge(other *Style)

type StyleColor added in v0.1.3

type StyleColor struct {
	// contains filtered or unexported fields
}
var StyleColorNone StyleColor = StyleColor{/* contains filtered or unexported fields */}

func NewStyleColor added in v0.1.3

func NewStyleColor(color Color) StyleColor

func (*StyleColor) Color added in v0.1.3

func (c *StyleColor) Color() Color

func (*StyleColor) IsNone added in v0.1.3

func (c *StyleColor) IsNone() bool

func (*StyleColor) IsZero added in v0.1.3

func (c *StyleColor) IsZero() bool

func (*StyleColor) SetColor added in v0.1.3

func (c *StyleColor) SetColor(color Color)

func (*StyleColor) SetNone added in v0.1.3

func (c *StyleColor) SetNone()

func (*StyleColor) String added in v0.1.3

func (c *StyleColor) String() string

func (*StyleColor) UnmarshalJSON added in v0.1.3

func (c *StyleColor) UnmarshalJSON(data []byte) error

type Stylesheet

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

Stylesheet represents a set of reusable styles that allow for style information to be defined separately from individual elements.

It is loosely modeled on a simplified version of CSS, basically only supporting classes.

func (*Stylesheet) AddRule

func (ss *Stylesheet) AddRule(sel Selector, style *Style)

AddRule adds a new rule to the stylesheet

func (*Stylesheet) GetAllRules

func (ss *Stylesheet) GetAllRules() []Rule

GetAllRules returns all the rules in the stylesheet

func (*Stylesheet) GetRules

func (ss *Stylesheet) GetRules(classes []string) []Rule

GetRules returns all the rules matching the given classes

func (*Stylesheet) GetStyle

func (ss *Stylesheet) GetStyle(classes []string) *Style

GetStyle returns the combined style of all styles that match the given classes

func (*Stylesheet) HasRules

func (ss *Stylesheet) HasRules() bool

HasRule returns if the stylesheet has any rules defined

type Text

type Text struct {
	Attributes Attributes
	Pos        vec.Vec2
	Text       string
	Size       float32
	Anchor     TextAnchor
}

Text is some text drawn to the canvas

func NewText

func NewText(pos vec.Vec2, text string) *Text

func (*Text) GetAABB

func (t *Text) GetAABB() *AABB

func (*Text) GetAttributes

func (t *Text) GetAttributes() *Attributes

func (*Text) Render

func (t *Text) Render(r Renderer) error

type TextAnchor

type TextAnchor int
const (
	TextAnchorNone TextAnchor = iota
	TextAnchorStart
	TextAnchorMiddle
	TextAnchorEnd
)

func (TextAnchor) String

func (a TextAnchor) String() string

Jump to

Keyboard shortcuts

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