Home

Awesome

On The Fly

Build GoDoc License Report Card

New/experimental features:

The SVG related code has been refactored out, optimized and moved to the tinysvg package.

Online API Documentation

godoc.org

Generate HTML, CSS and SVG in one go

<img src="img/onthefly.png">

Create hardware accelerated 3D-graphics with three.js

<img src="img/threejs.png">

Experiment with AngularJS

<img src="img/angular.png">

Example for Negroni

package main

import (
    "fmt"
    "net/http"

    "github.com/urfave/negroni"
    "github.com/xyproto/onthefly"
    "github.com/xyproto/tinysvg"
)

// Generate a new SVG image
func svgImage() []byte {
    document, svg := tinysvg.NewTinySVG(128, 64)
    svg.Describe("Hello SVG")

    // x, y, radius, color
    svg.Circle(30, 10, 5, "red")
    svg.Circle(110, 30, 2, "green")
    svg.Circle(80, 40, 7, "blue")

    // x, y, font size, font family, text and color
    svg.Text(3, 60, 6, "Courier", "There will be cake", "#394851")

    return document.Bytes()
}

// Generate a new onthefly Page (HTML5 and CSS combined)
func indexPage(svgurl string) *onthefly.Page {

    // Create a new HTML5 page, with CSS included
    page := onthefly.NewHTML5Page("Demonstration")

    // Add some text
    page.AddContent(fmt.Sprintf("onthefly %.1f", onthefly.Version))

    // Change the margin (em is default)
    page.SetMargin(4)

    // Change the font family
    page.SetFontFamily("serif") // or: sans-serif

    // Change the color scheme
    page.SetColor("black", "#d0d0d0")

    // Include the generated SVG image on the page
    body, err := page.GetTag("body")
    if err == nil {
        // CSS attributes for the body tag
        body.AddStyle("font-size", "2em")
        body.AddStyle("font-family", "sans-serif")

        // Paragraph
        p := body.AddNewTag("p")

        // CSS style
        p.AddStyle("margin-top", "2em")

        // Image tag
        img := p.AddNewTag("img")

        // HTML attributes
        img.AddAttrib("src", svgurl)
        img.AddAttrib("alt", "Three circles")

        // CSS style
        img.AddStyle("width", "60%")
        img.AddStyle("border", "4px solid white")
    }

    return page
}

// Set up the paths and handlers then start serving.
func main() {
    fmt.Println("onthefly ", onthefly.Version)

    // Create a Negroni instance and a ServeMux instance
    n := negroni.Classic()
    mux := http.NewServeMux()

    // Publish the generated SVG as "/circles.svg"
    svgurl := "/circles.svg"
    mux.HandleFunc(svgurl, func(w http.ResponseWriter, req *http.Request) {
        w.Header().Add("Content-Type", "image/svg+xml")
        w.Write(svgImage())
    })

    // Generate a Page that includes the svg image
    page := indexPage(svgurl)
    // Publish the generated Page in a way that connects the HTML and CSS
    page.Publish(mux, "/", "/style.css", false)

    // Handler goes last
    n.UseHandler(mux)

    // Listen for requests at port 3000
    n.Run(":3000")
}

Example for net/http

package main

import (
    "fmt"
    "log"
    "net/http"
    "time"

    "github.com/xyproto/onthefly"
    "github.com/xyproto/tinysvg"
)

// Generate a new SVG image
func svgImage() []byte {
    document, svg := tinysvg.NewTinySVG(128, 64)
    svg.Describe("Hello SVG")

    // x, y, radius, color
    svg.Circle(30, 10, 5, "red")
    svg.Circle(110, 30, 2, "green")
    svg.Circle(80, 40, 7, "blue")

    // x, y, font size, font family, text and color
    svg.Text(3, 60, 6, "Courier", "There will be cake", "#394851")

    return document.Bytes()
}

// Generate a new onthefly Page (HTML5 and CSS combined)
func indexPage(svgurl string) *onthefly.Page {

    // Create a new HTML5 page, with CSS included
    page := onthefly.NewHTML5Page("Demonstration")

    // Add some text
    page.AddContent(fmt.Sprintf("onthefly %.1f", onthefly.Version))

    // Change the margin (em is default)
    page.SetMargin(4)

    // Change the font family
    page.SetFontFamily("serif") // or: sans-serif

    // Change the color scheme
    page.SetColor("black", "#d0d0d0")

    // Include the generated SVG image on the page
    body, err := page.GetTag("body")
    if err == nil {

        // CSS attributes for the body tag
        body.AddStyle("font-size", "2em")
        body.AddStyle("font-family", "sans-serif")

        // Paragraph
        p := body.AddNewTag("p")

        // CSS style
        p.AddStyle("margin-top", "2em")

        // Image tag
        img := p.AddNewTag("img")

        // HTML attributes
        img.AddAttrib("src", svgurl)
        img.AddAttrib("alt", "Three circles")

        // CSS style
        img.AddStyle("width", "60%")
        img.AddStyle("border", "4px solid white")
    }

    return page
}

// Set up the paths and handlers then start serving.
func main() {
    fmt.Println("onthefly ", onthefly.Version)

    // Create a mux
    mux := http.NewServeMux()

    // Publish the generated SVG as "/circles.svg"
    svgurl := "/circles.svg"
    mux.HandleFunc(svgurl, func(w http.ResponseWriter, req *http.Request) {
        w.Header().Add("Content-Type", "image/svg+xml")
        w.Write(svgImage())
    })

    // Generate a Page that includes the svg image
    page := indexPage(svgurl)

    // Publish the generated Page in a way that connects the HTML and CSS
    page.Publish(mux, "/", "/style.css", false)

    // Configure the HTTP server and permissionHandler struct
    s := &http.Server{
        Addr:           ":3000",
        Handler:        mux,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }
    log.Println("Listening for requests on port 3000")

    // Start listening
    log.Fatal(s.ListenAndServe())
}

Additional screenshots

Screenshots from version 0.8:

<img src="img/svg_dark.png"> <img src="img/svg_light.png">

Version, license and author