Visualize.Backend.CanvasBinary (Visualize v0.2.25)

Copy Markdown View Source

Binary encoding for Canvas 2D rendering commands.

Packs an element tree into a compact little-endian stream of records that the CanvasBinaryChart hook (Visualize.Hooks.CanvasBinary) replays on a Canvas 2D context. The byte-level contract is spec/09 §4.

Records

A stream is a concatenation of records; each begins with one opcode byte from Visualize.Backend.CanvasBinary.Opcodes, which fixes its layout:

NameByteRecord
path0x01count:u32 then count points x:f64 y:f64 — one open polyline
path_cubic0x02count:u32 then count path commands, each a sub-opcode and its f64 arguments
circles0x03count:u32 then cx:f64 cy:f64 r:f64 per circle
rects0x04count:u32 then x:f64 y:f64 w:f64 h:f64 per rectangle
path320x05path with every coordinate an f32
path_cubic320x06path_cubic with every f64 argument an f32
cubic_run0x07count:u32, the start point x0:f32 y0:f32, then six f32 per cubic curve, no sub-opcodes
style0x10flags:u8 then the fields the flags select: fill RGBA, stroke RGBA, stroke_width:f32, opacity:f32
transform0x20kind:u8 then tx ty (0x01), tx ty sx sy (0x03) or a full matrix a b c d e f (0xFF), all f64
save0x30ctx.save()
restore0x31ctx.restore()
fill0x40ctx.fill() on the current path
stroke0x41ctx.stroke() on the current path

The point-list record is used only for a path that is one M followed by L commands, and the cubic run only for one M followed by C commands — the shapes those records hold without loss, the run being what a curve generator emits (D-74); every other path is a command stream, with the smooth curves S/T expanded to C/Q first so the command count is exact (D-36). Both come in an f32 and an f64 form: the encoder writes the f32 records by default, since a canvas coordinate is a pixel position and an f32 holds a value below 16,384 to within 2⁻¹¹ px, and precision: :f64 selects the f64 records (D-73; spec/09 §4.5). Transforms fold into one matrix in SVG order. Colours are parsed by Visualize.Color.parse/1.

Performance

Binary encoding reduces payload size by ~80% compared to JSON and eliminates JSON parsing overhead in the browser. The browser can create typed-array views directly on the binary data.

Requirements

Requires the nx package to be installed.

Summary

Types

The coordinate width of the path records: f32 by default (D-73).

Functions

Checks if Nx is available for binary encoding.

Encodes an element tree as binary data.

Encodes element, raising on error. Options as encode_path/2.

As encode_path/2 with no options.

Encodes a path element as binary data.

As encode_path!/2 with no options.

Encodes a path element as binary, raising on error. Options as encode_path/2.

Encodes binary data as base64 for embedding in HTML attributes.

Types

precision()

@type precision() :: :f32 | :f64

The coordinate width of the path records: f32 by default (D-73).

Functions

available?()

@spec available?() :: boolean()

Checks if Nx is available for binary encoding.

encode_element(element)

@spec encode_element(Visualize.IR.Element.t() | Visualize.SVG.Element.t()) ::
  {:ok, binary()} | {:error, :nx_not_available}

As encode_element/2 with no options.

encode_element(element, opts)

@spec encode_element(Visualize.IR.Element.t() | Visualize.SVG.Element.t(), keyword()) ::
  {:ok, binary()} | {:error, :nx_not_available}

Encodes an element tree as binary data.

Returns a binary blob that can be sent to the browser and decoded by the CanvasBinaryChart JavaScript hook.

Accepts either Visualize.IR.Element or Visualize.SVG.Element structs. Options as encode_path/2; the precision governs every path record in the stream.

encode_element!(element)

@spec encode_element!(Visualize.IR.Element.t() | Visualize.SVG.Element.t()) ::
  binary()

As encode_element!/2 with no options.

encode_element!(element, opts)

@spec encode_element!(Visualize.IR.Element.t() | Visualize.SVG.Element.t(), keyword()) ::
  binary()

Encodes element, raising on error. Options as encode_path/2.

encode_path(path)

@spec encode_path(Visualize.IR.Path.t()) ::
  {:ok, binary()} | {:error, :nx_not_available}

As encode_path/2 with no options.

encode_path(path, opts)

@spec encode_path(Visualize.IR.Path.t(), keyword()) ::
  {:ok, binary()} | {:error, :nx_not_available}

Encodes a path element as binary data.

Returns {:ok, binary} on success or {:error, reason} if Nx is not available.

Options

  • :precision - :f32 (the default) writes the path32/path_cubic32 records, :f64 the path/path_cubic ones (spec/09 §4.5)

encode_path!(path)

@spec encode_path!(Visualize.IR.Path.t()) :: binary()

As encode_path!/2 with no options.

encode_path!(path, opts)

@spec encode_path!(Visualize.IR.Path.t(), keyword()) :: binary()

Encodes a path element as binary, raising on error. Options as encode_path/2.

to_base64(binary)

@spec to_base64(binary()) :: String.t()

Encodes binary data as base64 for embedding in HTML attributes.