Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Nightre/Rapid.js/llms.txt

Use this file to discover all available pages before exploring further.

Rapid is the central class of the engine — every draw call, texture, matrix operation, and render target flows through a single instance of it. You create one Rapid per canvas element, pass in your configuration options, and then drive each frame with clear() / draw / flush().

Creating a Renderer

Pass an IAppOptions object to the Rapid constructor. Only canvas is required; all other fields have sensible defaults.
import { Rapid, TextureFilterMode, CanvasScaleMode } from "rapid.js";

const rapid = new Rapid({
  canvas: document.getElementById("canvas") as HTMLCanvasElement,
  logicWidth: 960,
  logicHeight: 540,
  backgroundColor: Color.fromHex("#1a1a2e"),
  textureFilter: TextureFilterMode.NEAREST,
});

IAppOptions Reference

canvas
HTMLCanvasElement
required
The HTML canvas element to render onto. Rapid acquires a WebGL2RenderingContext from this element at construction time.
logicWidth
number
The logical width of the application in CSS pixels. This defines the coordinate space used for all draw calls and the orthographic projection. Defaults to physicsWidth / dpr when omitted.
logicHeight
number
The logical height of the application in CSS pixels. Defaults to physicsHeight / dpr when omitted.
physicsWidth
number
The physical (GPU backbuffer) width in actual device pixels. Defaults to canvas.clientWidth * devicePixelRatio.
physicsHeight
number
The physical (GPU backbuffer) height in actual device pixels. Defaults to canvas.clientHeight * devicePixelRatio.
backgroundColor
Color
The default clear color applied at the start of each frame via rapid.clear(). Defaults to opaque black (Color.Black).
antialias
boolean
default:"false"
Requests MSAA antialiasing on the WebGL canvas context. Has no effect if the browser or GPU does not support it. Default is false.
textureFilter
TextureFilterMode
default:"TextureFilterMode.NEAREST"
The default sampling filter applied when new textures are created. NEAREST produces crisp pixel art; LINEAR produces smooth bilinear interpolation. Individual textures can override this via ITextureOptions.
premultipliedAlpha
boolean
default:"true"
Controls whether textures are uploaded and blended using premultiplied alpha. Keeping this true avoids “dark fringe” artifacts around transparent edges and matches the WebGL default. Default is true.
roundPixels
boolean
default:"false"
When true, sprite positions are snapped to the nearest integer pixel before rendering. Reduces sub-pixel shimmer on pixel-art assets at the cost of slightly less smooth motion.
scaleMode
CanvasScaleMode
default:"CanvasScaleMode.CanvasItem"
Controls how the canvas responds to DPI and CSS display size. See Canvas Scale Modes below.

Canvas Scale Modes

CanvasScaleMode controls the relationship between the WebGL backbuffer resolution and the CSS display size of the <canvas> element.

CanvasScaleMode.CanvasItem (default)

The WebGL backbuffer is sized at physicsWidth × physicsHeight (the CSS display size multiplied by the device pixel ratio). Rendering therefore happens at the full display resolution, so rotated sprites, lines, and geometry receive more rasterized pixels and look smoother. The logical coordinate space (and thus all draw-call coordinates) remains at logicWidth × logicHeight regardless of DPI — ideal for games targeting HD and Retina displays.
const rapid = new Rapid({
  canvas,
  logicWidth: 480,
  logicHeight: 270,
  scaleMode: CanvasScaleMode.CanvasItem,
  // On a 2× Retina screen the backbuffer is 960×540,
  // but your coordinate space remains 480×270.
});

CanvasScaleMode.Viewport

The WebGL backbuffer is sized at exactly logicWidth × logicHeight. The browser then stretches the canvas bitmap to fit the CSS display size using image-rendering: pixelated. No extra GPU fragments are produced while scaling up — this is the correct choice for pixel-art games that must preserve a low-resolution look.
const rapid = new Rapid({
  canvas,
  logicWidth: 320,
  logicHeight: 180,
  scaleMode: CanvasScaleMode.Viewport,
  // The backbuffer is always 320×180; the browser scales the bitmap.
});
CanvasScaleMode.Viewport automatically sets image-rendering: pixelated on the canvas element so the browser does not blur the upscaled image.

Frame Lifecycle

Every game loop follows the same three-step pattern: clear, draw, flush.

rapid.clear()

Clears the color buffer and the stencil buffer using backgroundColor, resets the draw call counter (drawcallCount) to zero, and resets the matrix stack to the identity transform. Call this at the beginning of every frame before issuing any draw calls.
function gameLoop() {
  rapid.clear();

  rapid.drawSprite({ texture: playerTex, x: 100, y: 200 });
  rapid.drawRect({ x: 0, y: 0, width: 960, height: 540, color: skyColor });

  rapid.flush();
  requestAnimationFrame(gameLoop);
}

rapid.flush()

Submits all pending batched draw calls to the GPU. Rapid batches geometry internally to minimize WebGL draw calls; flush() drains that batch. Call it at the end of every frame. It is also called automatically whenever the engine must switch rendering regions (e.g. changing blend mode or entering a render texture).

rapid.resize(logicWidth, logicHeight)

Updates the canvas dimensions, recalculates physicsWidth / physicsHeight, and rebuilds the orthographic projection matrix. Call this whenever the browser window resizes.
window.addEventListener("resize", () => {
  const w = window.innerWidth;
  const h = window.innerHeight;
  rapid.resize(w, h);
});
When scaleMode is CanvasScaleMode.Viewport the logical coordinate space stays fixed at your design resolution — you typically do not need to call resize() on window resize. It is most useful with CanvasItem mode where you want the logical space to track the window.

Camera with renderCamera

rapid.renderCamera(transform) applies a transform to the current matrix (position, rotation, scale) and then inverts it in place. This makes everything drawn afterwards appear as if the viewport has been scrolled or rotated by that transform — a lightweight, zero-overhead camera.
function gameLoop() {
  rapid.clear();

  rapid.matrixStack.save();
  rapid.renderCamera({ x: cameraX, y: cameraY });

  // All world-space sprites are now offset by the camera.
  for (const entity of worldEntities) {
    rapid.drawSprite({ texture: entity.tex, x: entity.x, y: entity.y });
  }

  rapid.matrixStack.restore();

  // HUD draws after restore — unaffected by the camera.
  rapid.drawSprite({ texture: hudTex, x: 0, y: 0 });

  rapid.flush();
}
renderCamera mutates the current world matrix. Always wrap it in a matrixStack.save() / matrixStack.restore() pair so the camera transform does not bleed into subsequent draw calls such as HUD elements.

Public Properties

These read-only properties are useful for layout, responsive design, and debugging.
PropertyTypeDescription
drawcallCountnumberNumber of WebGL draw calls issued in the current frame. Reset by clear().
logicWidthnumberCurrent logical width in CSS pixels.
logicHeightnumberCurrent logical height in CSS pixels.
physicsWidthnumberCurrent GPU backbuffer width in device pixels.
physicsHeightnumberCurrent GPU backbuffer height in device pixels.
dprnumberDevice pixel ratio (window.devicePixelRatio), captured at construction.
matrixStackMatrixStackThe hierarchical transform stack. See Transforms.
textureTextureManagerThe texture loader and cache. See Textures.

Responsive Resize Example

The following snippet wires resize() to the window and maintains a fixed aspect ratio.
const LOGIC_W = 960;
const LOGIC_H = 540;

const rapid = new Rapid({
  canvas: document.getElementById("canvas") as HTMLCanvasElement,
  logicWidth: LOGIC_W,
  logicHeight: LOGIC_H,
  scaleMode: CanvasScaleMode.CanvasItem,
});

function onResize() {
  // Keep the canvas filling the window while the logical space stays fixed.
  const scale = Math.min(
    window.innerWidth / LOGIC_W,
    window.innerHeight / LOGIC_H
  );
  const cssW = Math.round(LOGIC_W * scale);
  const cssH = Math.round(LOGIC_H * scale);

  rapid.resize(LOGIC_W, LOGIC_H, cssW, cssH);
}

window.addEventListener("resize", onResize);
onResize();

Build docs developers (and LLMs) love