Documentation
¶
Overview ¶
Package ultralightui renders HTML views as Ebiten textures using Ultralight 1.4.
It provides a simple API for embedding HTML/CSS/JS interfaces in Ebitengine games and applications, with bidirectional Go <-> JavaScript communication.
Basic usage:
import "github.com/YindSoft/ultralight-ebitengine-port"
// Create a UI from a local HTML file, a URL, or raw HTML bytes:
ui, err := ultralightui.NewFromFile(800, 600, "ui/index.html", nil)
// or: ultralightui.NewFromURL(800, 600, "https://example.com", nil)
// or: ultralightui.NewFromHTML(800, 600, htmlBytes, nil)
if err != nil { ... }
defer ui.Close()
// Receive messages from the page (JS calls go.send("action") or go.send({key: "val"}))
ui.OnMessage = func(msg string) {
data, _ := ultralightui.ParseMessage(msg) // parses JSON if applicable
...
}
// In Ebiten Update():
ui.Update()
// In Ebiten Draw():
screen.DrawImage(ui.GetTexture(), opts)
// Optional: restrict input to a screen region and manage keyboard focus
ui.SetBounds(0, 0, 800, 600)
ui.SetFocus()
// Send structured data to the page (serialized as JSON):
ui.Send(map[string]any{"hp": 80, "maxHp": 100})
// HTML receives it via: go.receive = function(data) { ... }
// Run arbitrary JavaScript:
ui.Eval("updateScore(100)")
Embedded assets (VFS):
Use NewFromFS to load HTML/CSS/JS/images from an embed.FS or any fs.FS. Files are registered in a virtual file system so Ultralight serves them from memory, without exposing assets on disk:
//go:embed ui var uiFiles embed.FS ui, err := ultralightui.NewFromFS(800, 600, "ui/index.html", uiFiles, nil)
JS -> Go communication uses native JavaScriptCore bindings (no console.log hacks). Go -> JS communication calls window.go.receive(data) with parsed JSON.
Multiple UltralightUI instances are supported. Each has its own Ultralight view. Mouse and scroll input are forwarded when the cursor is inside the view's bounds. Keyboard input goes to whichever view has focus (via SetFocus or clicking).
Requirements: the bridge shared library (ul_bridge.dll on Windows, libul_bridge.so on Linux, libul_bridge.dylib on macOS) and the Ultralight 1.4 SDK libraries must be present next to the executable or in the directory specified by [Options.BaseDir].
Index ¶
- Variables
- func ClearFiles()
- func ClearFocus()
- func ParseMessage(msg string) (interface{}, error)
- func RegisterFile(filePath string, data []byte) error
- func Tick()
- func VFSFileCount() int
- type Options
- type UltralightUI
- func New(width, height int, htmlPath string, opts *Options) (*UltralightUI, error)
- func NewFromFS(width, height int, mainFile string, fsys fs.FS, opts *Options) (*UltralightUI, error)
- func NewFromFSAsync(width, height int, mainFile string, fsys fs.FS, opts *Options) (*UltralightUI, error)
- func NewFromFile(width, height int, filePath string, opts *Options) (*UltralightUI, error)
- func NewFromHTML(width, height int, html []byte, opts *Options) (*UltralightUI, error)
- func NewFromURL(width, height int, url string, opts *Options) (*UltralightUI, error)
- func (ui *UltralightUI) Close()
- func (ui *UltralightUI) Eval(script string)
- func (ui *UltralightUI) GetTexture() *ebiten.Image
- func (ui *UltralightUI) IsReady() bool
- func (ui *UltralightUI) MarkDirty()
- func (ui *UltralightUI) Send(data interface{}) error
- func (ui *UltralightUI) SetBounds(x, y, w, h int)
- func (ui *UltralightUI) SetFocus()
- func (ui *UltralightUI) Update() error
- func (ui *UltralightUI) UpdateNoTick() error
Constants ¶
This section is empty.
Variables ¶
var GlobalCursorOffsetX int
GlobalCursorOffsetX/Y se restan de las coordenadas del cursor antes de verificar bounds y calcular coordenadas locales. Usar cuando el área de contenido no empieza en (0,0) (ej: un borde + topbar desplazan el contenido).
var GlobalCursorOffsetY int
Functions ¶
func ClearFiles ¶ added in v0.1.0
func ClearFiles()
ClearFiles frees all files registered in the VFS.
func ClearFocus ¶ added in v0.1.1
func ClearFocus()
ClearFocus removes keyboard focus from all views. After this call, no UI receives key events (keys go back to the game).
func ParseMessage ¶
ParseMessage parses msg as JSON if it looks like JSON (starts with '{' or '['). Returns the parsed value, or the raw string if it's not JSON.
func RegisterFile ¶ added in v0.1.0
RegisterFile registers a file in Ultralight's VFS. filePath is the virtual path (e.g., "ui/style.css"). data is the content. Registered files take priority over disk files. Must be called BEFORE creating views that reference them.
func Tick ¶ added in v0.1.1
func Tick()
Tick calls the Ultralight renderer once (Update + RefreshDisplay + Render for all views). When using multiple views, call Tick() once per frame BEFORE calling UpdateNoTick() on each view. This avoids redundant renderer cycles that happen when each view calls Update().
func VFSFileCount ¶ added in v0.1.0
func VFSFileCount() int
VFSFileCount returns the number of files registered in the VFS.
Types ¶
type Options ¶
type Options struct {
BaseDir string // Directory containing the bridge shared library and Ultralight SDK libraries. Defaults to working directory.
Debug bool // Enable debug logging (creates bridge.log and ultralight.log). Default false.
}
Options for creating the UI. All fields are optional.
type UltralightUI ¶
type UltralightUI struct {
// Bounds in screen coordinates for input routing. Set via SetBounds so that
// only the view under the cursor receives mouse/scroll input.
BoundsX, BoundsY, BoundsW, BoundsH int
// OnMessage is called when the page sends a message via go.send(msg).
// msg is a string or JSON string. Use ParseMessage to get structured data.
OnMessage func(msg string)
// contains filtered or unexported fields
}
UltralightUI represents an HTML view rendered as an Ebiten texture. Multiple instances can exist; each has its own view in the Ultralight bridge.
func New ¶
func New(width, height int, htmlPath string, opts *Options) (*UltralightUI, error)
New is a convenience alias for NewFromFile.
func NewFromFS ¶ added in v0.1.0
func NewFromFS(width, height int, mainFile string, fsys fs.FS, opts *Options) (*UltralightUI, error)
NewFromFS creates a new UI loading all files from the given fs.FS into Ultralight's VFS, then loads mainFile as the main page.
mainFile is relative to the FS root (e.g., "ui/index.html"). All files in the FS are registered so that <link>, <script>, <img> can reference them with relative paths.
Example with embed.FS:
//go:embed ui var uiFiles embed.FS ui, err := ultralightui.NewFromFS(800, 600, "ui/index.html", uiFiles, nil)
func NewFromFSAsync ¶ added in v0.1.1
func NewFromFSAsync(width, height int, mainFile string, fsys fs.FS, opts *Options) (*UltralightUI, error)
NewFromFSAsync is like NewFromFS but creates the view asynchronously. The view is returned immediately but is not yet ready to use. Call IsReady() to check when loading is complete (~5 ticks / ~83ms). Update() can be called immediately; it handles the async state gracefully. Pixel output will be empty/transparent until the view is ready.
func NewFromFile ¶
func NewFromFile(width, height int, filePath string, opts *Options) (*UltralightUI, error)
NewFromFile creates a new UI loading HTML from a local file.
func NewFromHTML ¶
func NewFromHTML(width, height int, html []byte, opts *Options) (*UltralightUI, error)
NewFromHTML creates a new UI with the given HTML bytes (no file or URL).
func NewFromURL ¶
func NewFromURL(width, height int, url string, opts *Options) (*UltralightUI, error)
NewFromURL creates a new UI loading content from a URL.
func (*UltralightUI) Close ¶
func (ui *UltralightUI) Close()
Close releases resources. Call when done (e.g. defer ui.Close()). After Close, the UI must not be used.
func (*UltralightUI) Eval ¶
func (ui *UltralightUI) Eval(script string)
Eval runs JavaScript in the page. Fire-and-forget (no return value).
func (*UltralightUI) GetTexture ¶
func (ui *UltralightUI) GetTexture() *ebiten.Image
GetTexture returns the Ebiten image with the current HTML content rendered.
func (*UltralightUI) IsReady ¶ added in v0.1.1
func (ui *UltralightUI) IsReady() bool
IsReady returns true if the view has finished async loading and is usable. For synchronously created views this always returns true. For async views (NewFromFSAsync), it returns false until priming+loading is done.
func (*UltralightUI) MarkDirty ¶ added in v0.1.1
func (ui *UltralightUI) MarkDirty()
MarkDirty es un no-op mantenido por compatibilidad. Los pixels se copian automaticamente cada frame cuando Ultralight tiene cambios pendientes.
func (*UltralightUI) Send ¶
func (ui *UltralightUI) Send(data interface{}) error
Send sends structured data to the page. It serializes to JSON and invokes window.go.receive(data). Define go.receive in your HTML to handle it.
func (*UltralightUI) SetBounds ¶
func (ui *UltralightUI) SetBounds(x, y, w, h int)
SetBounds sets the screen rectangle for this UI. Mouse and scroll are only forwarded when the cursor is inside these bounds. Keyboard goes to the focused UI. Use (0,0,0,0) to disable input.
func (*UltralightUI) SetFocus ¶
func (ui *UltralightUI) SetFocus()
SetFocus gives this UI keyboard focus. Only the focused UI receives key events, regardless of cursor position. Mouse and scroll still require the cursor inside bounds. Clicking inside a UI also gives it focus.
func (*UltralightUI) Update ¶
func (ui *UltralightUI) Update() error
Update should be called every frame from the game's Update. It ticks Ultralight, copies pixels to the texture, polls messages, and forwards input. Note: each call to Update() triggers a full renderer cycle for ALL views. For multiple views, prefer calling Tick() once then UpdateNoTick() on each view.
func (*UltralightUI) UpdateNoTick ¶ added in v0.1.1
func (ui *UltralightUI) UpdateNoTick() error
UpdateNoTick does everything Update() does EXCEPT calling ulTick(). Use with Tick(): call Tick() once per frame, then UpdateNoTick() on each view.
Directories
¶
| Path | Synopsis |
|---|---|
|
Example of NewFromFS: loads HTML/CSS/JS from embed.FS (no files on disk).
|
Example of NewFromFS: loads HTML/CSS/JS from embed.FS (no files on disk). |
