Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sanchedev/tiny-engine/llms.txt

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

Sprite is the primary rendering node. It draws a texture loaded with loadTexture() at the node’s position, optionally sliced from a sprite sheet via margin and sourceSize, and scaled up with displaySize. A full set of visual filters — brightness, contrast, saturation, hue rotation, grayscale, invert, opacity, and RGBA modulation — can all be driven reactively from signals. Sprite extends Node2D, so it also accepts position, id, zIndex, deltaIncrease, script, ref, and children.

Usage

import { loadTexture, Vector2 } from 'tiny-engine'
import { useRefNode } from 'tiny-engine/hooks'
import { PrimaryNode } from 'tiny-engine/nodes/enum'

const PLAYER_TEXTURE = await loadTexture('/assets/player.png')

function Player() {
  const sprite = useRefNode(PrimaryNode.Sprite)

  return (
    <sprite
      ref={sprite}
      textureId={PLAYER_TEXTURE}
      sourceSize={new Vector2(32, 32)}
      displaySize={new Vector2(64, 64)}
    />
  )
}

Props

Texture

textureId
symbol | SignalGetter<symbol>
The symbol returned by loadTexture(). The texture must be loaded before the scene starts. Setting this to null clears the sprite. Reactive when a SignalGetter is passed.
margin
VectorLike | SignalGetter<VectorLike>
Pixel offset into the source image where the slice begins. Use this to pick a specific frame from a packed sprite sheet.
sourceSize
VectorLike | SignalGetter<VectorLike>
Width and height of the region to read from the texture. Defaults to the full texture size when omitted.
displaySize
VectorLike | SignalGetter<VectorLike>
Width and height to draw on screen. Defaults to sourceSize. Useful for pixel-art upscaling without keeping a large source image.
flipX
boolean | SignalGetter<boolean>
Mirror the sprite horizontally. Defaults to false.
flipY
boolean | SignalGetter<boolean>
Mirror the sprite vertically. Defaults to false.

Filters

All filter props accept a static value or a reactive SignalGetter<number>. See Filters guide for worked examples.
brightness
number | SignalGetter<number>
Adjusts brightness. 0 = black, 1 = unchanged, 2 = fully white. Default: 1.
grayscale
number | SignalGetter<number>
Converts to grayscale. 0 = full color, 1 = fully desaturated. Default: 0.
modulate
Color | SignalGetter<Color>
Multiplies every pixel by an RGBA tint [r, g, b, a] where each channel is 01. Applied via multiply composite operation after the main draw. Default: [1, 1, 1, 1] (no tint).
contrast
number | SignalGetter<number>
Adjusts contrast. 0 = flat grey, 1 = unchanged, 2 = double contrast. Default: 1.
saturate
number | SignalGetter<number>
Adjusts color saturation. 0 = desaturated, 1 = unchanged, 2 = double saturation. Default: 1.
hueRotate
number | SignalGetter<number>
Rotates the hue wheel in degrees. 0 = unchanged, 180 = complementary colors, 360 = full rotation. Default: 0.
invert
number | SignalGetter<number>
Inverts all colors. 0 = normal, 1 = fully inverted. Default: 0.
opacity
number | SignalGetter<number>
Overall transparency. 0 = invisible, 1 = fully opaque. Default: 1.

Events

Sprite inherits all base node events. Subscribe with useEvent.
Event nameCallback signatureDescription
started() => voidFires once after the texture is loaded.
updated(delta: number) => voidFires every frame during the update cycle.
drawed(delta: number) => voidFires every frame during the draw cycle.
destroyed() => voidFires once when the node is removed.

Example — reactive brightness on hover

Combine Clickable + a signal to create a hover-brighten button effect.
import { loadTexture, Vector2 } from 'tiny-engine'
import { useSignal, useRefNode, useEvent } from 'tiny-engine/hooks'
import { PrimaryNode } from 'tiny-engine/nodes/enum'

const BTN_TEXTURE = await loadTexture('/assets/button.png')

function HoverButton() {
  const [bright, setBright] = useSignal(1)

  return (
    <transform position={new Vector2(200, 150)}>
      <sprite
        textureId={BTN_TEXTURE}
        sourceSize={new Vector2(64, 32)}
        displaySize={new Vector2(128, 64)}
        brightness={bright}
      />
      <clickable
        size={new Vector2(128, 64)}
        onMouseEnter={() => setBright(1.4)}
        onMouseExit={() => setBright(1)}
      />
    </transform>
  )
}

Example — sprite sheet frame

Slice a single 16×16 frame from a horizontal strip at column 2 (zero-indexed).
<sprite
  textureId={WALK_TEXTURE}
  margin={new Vector2(32, 0)}
  sourceSize={new Vector2(16, 16)}
  displaySize={new Vector2(32, 32)}
/>
The texture must be registered with loadTexture() before the scene mounts. Passing an unregistered symbol will render nothing without throwing at construction time.
For animated sprites, pair Sprite with an AnimationPlayer child node rather than manually updating margin each frame.
  • AnimationPlayer — frame-based animation driven by the sprite’s margin
  • Transform — position the sprite in world space
  • Filters guide — detailed examples for every filter prop
  • useSignal — create reactive values to drive filter props

Build docs developers (and LLMs) love