OpenFresco (open_fresco v0.1.0)

Copy Markdown View Source

OG-image / social-card scenes rendered server-side, built to run on Fresco canvases.

An OG template is a design with holes — the post title, hero image, and CTA label are substituted per post (and per locale) at render time, not baked into the design. OpenFresco models that as a Scene of positioned elements whose text/image values may be placeholders, then resolves those values and emits the result.

This v0.1 slice produces SVG (render_svg/3) — the shared intermediate representation. A later, optional native dependency will rasterize the same SVG to PNG (render/3, not yet available). Because both the editor preview and the final raster come from one SVG generator, "what you edit is what renders" holds by construction.

Quick start

scene =
  OpenFresco.Scene.new(width: 1200, height: 630, background: OpenFresco.Scene.solid("#0b1220"))
  |> OpenFresco.Scene.add(
    OpenFresco.Scene.text("title",
      box: %{x: 64, y: 420, w: 1072, h: 150},
      value: OpenFresco.Scene.placeholder("title"),
      size: 68, weight: 700, fill: OpenFresco.Scene.solid("#ffffff")
    )
  )

svg = OpenFresco.render_svg(scene, %{"title" => "Hello, world"})

Determinism & caching

render_svg/3 is a pure function of (scene, values). version/0 returns the generator version string — fold it into cache keys so cached output invalidates when the generator changes.

Not fresco-coupled at render time

A Scene is standalone. It is carried inside a Fresco canvas's extensions["open_fresco"] blob for editing and storage (non-breaking for etcher/tessera, which own their own extension keys), but rendering needs no fresco dependency — this package depends only on :jason.

Summary

Functions

Whether a PNG rasterizer backend is available (see render/3).

Render a scene to PNG bytes{:ok, png, %{width, height}} or {:error, term}. Browser-free, deterministic, never raises. Requires a rasterizer backend (the optional :resvg dep, or a CLI on PATH); returns {:error, :rasterizer_missing} when none is reachable. See OpenFresco.Renderer.

Render a scene to SVG (a binary), resolving values.

The SVG-generator version string, for folding into cache keys.

Functions

rasterizer_available?()

@spec rasterizer_available?() :: boolean()

Whether a PNG rasterizer backend is available (see render/3).

render(scene, values \\ %{}, opts \\ [])

@spec render(OpenFresco.Scene.t(), map(), keyword()) ::
  {:ok, binary(), %{width: pos_integer(), height: pos_integer()}}
  | {:error, term()}

Render a scene to PNG bytes{:ok, png, %{width, height}} or {:error, term}. Browser-free, deterministic, never raises. Requires a rasterizer backend (the optional :resvg dep, or a CLI on PATH); returns {:error, :rasterizer_missing} when none is reachable. See OpenFresco.Renderer.

render_svg(scene, values \\ %{}, opts \\ [])

@spec render_svg(OpenFresco.Scene.t(), map(), keyword()) :: binary()

Render a scene to SVG (a binary), resolving values.

values maps {{slot}} (and [[global]]) names to resolved values. Inline tokens are substituted inside text and image strings; an unwired {{slot}} passes through visibly (og's "needs wiring" signal), and a missing image slot draws the neutral "unresolved image" stand-in. Locale is a render input — pass locale-resolved values (or a [[page_locale]] global).

Options:

  • :globals — a map of [[global]] values (site host, page URL, locale…), merged with values before substitution.
  • :max_dimension — clamp canvas width/height to this many pixels (default 10_000) as an OOM guard against crafted scenes.

version()

@spec version() :: String.t()

The SVG-generator version string, for folding into cache keys.