Convert Figma logo to code with AI

tdewolff logocanvas

Cairo in Go: vector to raster, SVG, PDF, EPS, WASM, OpenGL, Gio, etc.

1,479
99
1,479
20

Top Related Projects

4,378

Go Graphics - 2D rendering in Go with a simple API.

1,085

2D rendering for different output (raster, pdf, svg)

2,138

Go Language Library for SVG generation

Quick Overview

tdewolff/canvas is a Go library for vector graphics rendering. It provides a powerful and flexible API for creating complex graphics, supporting various output formats including SVG, PDF, and raster images. The library aims to offer high performance and extensive features for 2D drawing tasks.

Pros

  • High-performance rendering with optimized algorithms
  • Support for multiple output formats (SVG, PDF, PNG, etc.)
  • Extensive set of drawing primitives and operations
  • Clean and intuitive API design

Cons

  • Limited documentation and examples compared to some other graphics libraries
  • Steeper learning curve for beginners due to its comprehensive feature set
  • Lack of built-in support for some advanced graphical effects (e.g., complex gradients)

Code Examples

  1. Creating a simple shape:
import "github.com/tdewolff/canvas"

c := canvas.New(100, 100)
ctx := canvas.NewContext(c)
ctx.SetFillColor(canvas.Black)
ctx.DrawCircle(50, 50, 30)
ctx.Fill()
  1. Drawing text:
import "github.com/tdewolff/canvas"

c := canvas.New(200, 100)
ctx := canvas.NewContext(c)
face := canvas.NewFontFamily("sans-serif")
face.LoadSystemFont("Arial")
ctx.SetFont(face, 24)
ctx.DrawText(10, 50, "Hello, Canvas!")
  1. Saving to different formats:
import (
    "github.com/tdewolff/canvas"
    "github.com/tdewolff/canvas/renderers"
)

c := canvas.New(100, 100)
// ... drawing operations ...

renderers.Write("output.svg", c)
renderers.Write("output.pdf", c)
renderers.Write("output.png", c)

Getting Started

To use tdewolff/canvas in your Go project:

  1. Install the library:

    go get -u github.com/tdewolff/canvas
    
  2. Import the package in your Go code:

    import "github.com/tdewolff/canvas"
    
  3. Create a new canvas and context:

    c := canvas.New(width, height)
    ctx := canvas.NewContext(c)
    
  4. Use the context to draw shapes, text, or images, and then save the output using the appropriate renderer.

Competitor Comparisons

4,378

Go Graphics - 2D rendering in Go with a simple API.

Pros of gg

  • Simpler API with fewer concepts to learn
  • Better suited for quick, straightforward drawing tasks
  • More extensive documentation and examples

Cons of gg

  • Less feature-rich compared to canvas
  • Limited support for advanced text rendering and font handling
  • Fewer options for fine-grained control over drawing operations

Code Comparison

gg:

dc := gg.NewContext(1000, 1000)
dc.DrawCircle(500, 500, 400)
dc.SetRGB(0, 0, 0)
dc.Fill()
dc.SavePNG("output.png")

canvas:

c := canvas.New(1000, 1000)
ctx := canvas.NewContext(c)
ctx.SetFillColor(color.Black)
ctx.DrawCircle(500, 500, 400)
ctx.FillStroke()
c.SavePNG("output.png")

Both libraries provide similar functionality for basic drawing operations, but canvas offers more advanced features and greater flexibility at the cost of a slightly more complex API. gg is ideal for simpler projects or quick prototypes, while canvas is better suited for more complex graphics applications requiring fine-tuned control and advanced rendering capabilities.

1,085

2D rendering for different output (raster, pdf, svg)

Pros of draw2d

  • More mature project with longer development history
  • Wider range of drawing primitives and features
  • Better documentation and examples

Cons of draw2d

  • Slower performance for complex drawings
  • Less active development in recent years
  • Larger codebase and dependencies

Code Comparison

draw2d:

gc := draw2d.NewGraphicContext(dest)
gc.SetStrokeColor(color.Black)
gc.SetLineWidth(1)
gc.MoveTo(10, 10)
gc.LineTo(100, 100)

canvas:

ctx := canvas.NewContext(dest)
ctx.SetStrokeColor(color.Black)
ctx.SetLineWidth(1)
ctx.MoveTo(10, 10)
ctx.LineTo(100, 100)

Summary

Both draw2d and canvas are Go libraries for 2D graphics rendering. draw2d offers a more comprehensive set of features and has been around longer, making it a solid choice for complex drawing tasks. However, canvas provides better performance and is actively maintained, making it suitable for projects requiring efficiency and ongoing support. The API usage is similar between the two, allowing for relatively easy migration if needed.

2,138

Go Language Library for SVG generation

Pros of svgo

  • Simpler API, easier to get started for basic SVG creation
  • Lightweight and focused specifically on SVG generation
  • Includes built-in support for common SVG elements and attributes

Cons of svgo

  • Less feature-rich compared to canvas's broader graphics capabilities
  • Limited to SVG output, while canvas supports multiple output formats
  • Lacks advanced text rendering and font handling features

Code Comparison

svgo:

canvas := svg.New(os.Stdout)
canvas.Start(500, 500)
canvas.Circle(250, 250, 125, "fill:none;stroke:black")
canvas.Text(250, 250, "Hello, SVG!", "text-anchor:middle")
canvas.End()

canvas:

c := canvas.New(500, 500)
ctx := canvas.NewContext(c)
ctx.SetStrokeColor(color.Black)
ctx.DrawCircle(250, 250, 125)
ctx.SetFillColor(color.Black)
ctx.DrawText("Hello, Canvas!", 250, 250)

Both libraries offer straightforward ways to create basic shapes and text, but canvas provides more fine-grained control over drawing operations and styles. svgo's API is more concise for simple SVG generation, while canvas offers a more comprehensive set of drawing functions and greater flexibility in output formats.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Canvas

API reference User guide Go Report Card Coverage Status

API documentation

User guide

Live HTMLCanvas demo

Canvas is a common vector drawing target that can output SVG, PDF, EPS, raster images (PNG, JPG, GIF, ...), HTML Canvas through WASM, OpenGL, and Gio. It has a wide range of path manipulation functionality such as flattening, stroking and dashing implemented. Additionally, it has a text formatter and embeds and subsets fonts (TTF, OTF, WOFF, WOFF2, or EOT) or converts them to outlines. It can be considered a Cairo or node-canvas alternative in Go. See the example below in Figure 1 for an overview of the functionality.

Preview

Figure 1: top-left you can see text being fitted into a box, justified using Donald Knuth's linea breaking algorithm to stretch the spaces between words to fill the whole width. You can observe a variety of styles and text decorations applied, as well as support for LTR/RTL mixing and complex scripts. In the bottom-right the word "stroke" is being stroked and drawn as a path. Top-right we see a LaTeX formula that has been converted to a path. Left of that we see an ellipse showcasing precise dashing, notably the length of e.g. the short dash is equal wherever it is on the curve. Note that the dashes themselves are elliptical arcs as well (thus exactly precise even if magnified greatly). To the right we see a closed polygon of four points being smoothed by cubic Béziers that are smooth along the whole path, and the blue line on the left shows a smoothed open path. On the bottom you can see a rotated rasterized image. The bottom-left shows path boolean operations. The result is equivalent for all renderers (PNG, PDF, SVG, etc.).

Sponsors

I'm actively looking for support in the form of donations or sponsorships to keep developing this library and highly appreciate any gesture. Please see the Sponsors button in GitHub for ways to contribute, or contact me directly.

State

Whether this library is ready for production environments is up to your own judgment. In general, this library is written thoughtfully and complete, but the scope of this work is so big and the implementation can be quite complex that inevitably it must have a great amount of bugs. Effort was put in writing unit and fuzz tests so that I suspect only special use-cases will stumble into bugs, but coverage is still lacking. As time permits, work is done to flesh-out functionality, find bugs, and optimize code. Optimization could be in execution time / reducing code complexity, reducing memory footprint, or reducing the length of paths from operation.

Execution performance is actually really good, especially the rasterizer is highly optimized with ASM. See for example a comparison of an extreme case in https://github.com/tdewolff/canvas/issues/280#issuecomment-1995990038, where this library is at least twice as fast as existing solutions, and can handle bigger images than the likes of Inkscape and Cairo.

Please issue bug reports or feature requests to help this library mature! All help is appreciated. Also see Wiki - Planning for an inexhaustive list of ideas and TODOs.

Recent changes

  • Context view and coordinate view have been altered. View now doesn't affect the coordinate view/system. To achieve the same as before, replace ctx.SetView(m) by ctx.SetView(m); ctx.SetCoordView(m). The change makes coordinate systems more intuitive when using in combination with views, the given coordinate reflects the coordinate where it is drawn irrespective of the view. This has been reverted, the coordinate view is first performed to the coordinate, and then the view applies as a affine transformation matrix for all objects (including their coordinates). This less error prone (as evidenced by recents bugs in ParseSVG). If you previously used ctx.SetCoordView(m); ctx.SetView(m), now only the latter is needed. Otherwise, you may need to update your coordinates when using ctx.SetView(m).

Features

  • Path segment types: MoveTo, LineTo, QuadTo, CubeTo, ArcTo, Close
  • Precise path flattening, stroking, and dashing for all segment type uing papers (see below)
  • Smooth spline generation through points for open and closed paths
  • Path boolean operations: AND, OR, XOR, NOT, Divide
  • LaTeX to path conversion (native Go and CGO implementations available)
  • Font formats support
    • SFNT (such as TTF, OTF, WOFF, WOFF2, EOT) supporting TrueType, CFF, and CFF2 tables
  • HarfBuzz for text shaping (native Go and CGO implementations available)
  • FriBidi for text bidirectionality (native Go and CGO implementations available)
  • Donald Knuth's line breaking algorithm for text layout
  • sRGB compliance (use SRGBColorSpace, only available for rasterizer)
  • Font rendering with gamma correction of 1.43
  • Rendering targets
    • Raster images (PNG, GIF, JPEG, TIFF, BMP, WEBP)
    • PDF
    • SVG and SVGZ
    • PS and EPS
    • HTMLCanvas
    • OpenGL
  • Rendering sources
    • Canvas itself

Examples

Amsterdam city centre: the centre of Amsterdam is drawn from data loaded from the Open Street Map API.

Mauna-Loa CO2 concentration: using data from the Mauna-Loa observatory, carbon dioxide concentrations over time are drawn

Text document: an example of a text document using the PDF backend.

OpenGL: an example using the OpenGL backend.

Gio: an example using the Gio backend.

Fyne: an example using the Fyne backend.

TeX/PGF: an example showing the usage of the PGF (TikZ) LaTeX package as renderer in order to generated a PDF using LaTeX.

go-chart: an example using the go-chart library, plotting a financial graph.

gonum/plot: an example using the gonum/plot library.

HTMLCanvas: an example using the HTMLCanvas backend, see the live demo.

Users

This is a non-exhaustive list of library users I've come across. PRs are welcome to extend the list!

Articles

My own

Papers

License

Released under the MIT license.

Be aware that Fribidi uses the LGPL license.