Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

D.5 Canvas Graphics Intrinsics

The WASM backend provides intrinsics for canvas-based graphics with animation support:

IntrinsicArgsDescription
__canvas_init__(width height)2Initialize canvas and return RGBA pixel buffer pointer
__canvas_width__()0Get current canvas width
__canvas_height__()0Get current canvas height
__canvas_present__()0Copy pixel buffer to canvas (display frame)
__canvas_set_aspect_lock__(enabled)1Enable or disable aspect-ratio locking using a udewy bool
__frame_count__()0Get current animation frame number
__frame_time__()0Get milliseconds since canvas initialization
__window_width__()0Get browser window inner width
__window_height__()0Get browser window inner height

Usage:

  1. Call __canvas_init__(width height) to create a canvas and get a pointer to the pixel buffer
  2. Optionally call __canvas_set_aspect_lock__(true) to keep the displayed canvas centered at its current aspect ratio as the browser window resizes
  3. Call __canvas_set_aspect_lock__(false) later if you want to return to unrestricted fullscreen scaling
  4. Write RGBA pixels (4 bytes per pixel) to the buffer: [R, G, B, A, R, G, B, A, ...]
  5. Call __canvas_present__() to display the frame
  6. The runtime automatically calls main() each animation frame when canvas mode is active

__canvas_set_aspect_lock__(enabled) expects a udewy boolean value, normally passed as the true or false literals. Internally, any non-zero value enables the lock and 0 disables it.

When aspect lock is enabled, the runtime uses the canvas's current backing dimensions, typically the width and height passed to __canvas_init__(), as the aspect ratio to preserve.

Example:

let buffer:int = 0
let width:int = 320
let height:int = 240

let set_pixel = (x:int y:int r:int g:int b:int):>int => {
    let offset:int = ((y * width) + x) * 4
    let addr:int = buffer + offset
    __store_u8__(r addr)
    __store_u8__(g addr + 1)
    __store_u8__(b addr + 2)
    __store_u8__(255 addr + 3)
    return 0
}

let main = ():>int => {
    buffer = __canvas_init__(width height)
    let t:int = __frame_time__()
    
    # Draw something based on time...
    
    __canvas_present__()
    return 0
}