SplatViewer.Components (SplatViewer v0.1.1)

Copy Markdown View Source

The <.splat_viewer /> component.

<.splat_viewer src={~p"/scans/room.sog"} height="500px" />

Everything the browser needs travels as data attributes on a single element, which the SplatViewer hook reads on mount. That is deliberate: it means the viewer survives a LiveView patch that re-renders the element's attributes without re-mounting it, and it means the server never has to push a message to get the viewer started.

Validation happens here

Options are checked in Elixir rather than in the hook. A bad :camera is a compile-or-render-time error with a message naming what was wrong; the same mistake caught in JavaScript is a console warning nobody sees, on a page that renders an empty grey box. Anything that can be rejected before it crosses into the browser is rejected here.

Summary

Functions

Renders a Gaussian splat.

Functions

splat_viewer(assigns)

@spec splat_viewer(map()) :: Phoenix.LiveView.Rendered.t()

Renders a Gaussian splat.

Attributes

:src is the only required one. Point it at a .sog file — the compressed format splat_tools produces, roughly 45× smaller than the PLY a trainer emits. A .ply will load, and on a real capture it will cost your visitor a hundred megabytes to do it.

Examples

<.splat_viewer src={~p"/scans/room.sog"} />

<.splat_viewer
  src={~p"/scans/room.sog"}
  camera={@scan.camera}
  height="600px"
  autorotate
  class="rounded-lg shadow"
/>

Sizing

:height sets the element's height directly. For a responsive box, leave it alone and use :class with an aspect-ratio utility — the canvas fills its container and follows it through a ResizeObserver, so either works.

Attributes

  • src (:string) (required) - URL of the .sog (or .ply) file to display.

  • id (:string) - DOM id; generated from the src when omitted, which is enough when there is one per page. Defaults to nil.

  • camera (:any) - Starting viewpoint — a SplatViewer.Camera, or a map with position, target and optionally fov. Without one the viewer frames the scene's bounding box, which is a guess; SplatTools.prepare/3 derives a better one at conversion time.

    Defaults to nil.

  • height (:string) - CSS height for the container. Defaults to "480px".

  • autorotate (:boolean) - slowly orbit until the visitor interacts, then stop and stay stopped. Defaults to false.

  • background (:string) - hex colour behind the splat — #rgb, #rgba, #rrggbb or #rrggbbaa. Defaults to "#111318".

  • dpr_cap (:float) - Ceiling on device pixel ratio. The reason mobile struggles with splats is overdraw and alpha blending on a tiled GPU, not arithmetic, so rendering a 3× backing store costs nine times the fill rate for a screen nobody is holding to their eye. Capping is the single most effective mobile lever.

    Defaults to 2.0.

  • pause_offscreen (:boolean) - stop rendering while the element is scrolled out of view or the tab is hidden. Defaults to true.

  • interactive (:boolean) - allow orbit, pan and zoom. Defaults to true.

  • class (:string) - classes for the container element. Defaults to nil.

  • engine_url (:string) - Where to load the rendering engine from, overriding SplatViewer.engine_path/0 for this element.

    Defaults to nil.

  • glslang_url (:string) - URL of PlayCanvas's glslang shader compiler. Supply this and :twgsl_url to enable the WebGPU backend; without both, WebGL2 is used. Asking for WebGPU without them makes the engine log an error on every mount before falling back, so it is off by default.

    Defaults to nil.

  • twgsl_url (:string) - URL of PlayCanvas's twgsl shader compiler. Defaults to nil.

  • Global attributes are accepted.