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.

Clickable turns a rectangular region of the screen into an interactive hit area. Every frame it checks whether the pointer is inside a rectangle anchored at its world-space position with dimensions given by size. It fires mouseEntered on the first frame the pointer enters, mouseExited when it leaves, and clicked when a press-and-release cycle finishes inside the area. There is no default size — you must always pass size. Disable the node temporarily with disabled without removing it from the scene. Clickable extends Node2D, so it inherits position, id, zIndex, deltaIncrease, ref, script, and children.

Usage

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

function Button() {
  const btn = useRefNode(PrimaryNode.Clickable)

  useEvent(btn, 'clicked', (pos) => {
    console.log('Clicked at local position', pos.x, pos.y)
  })

  return (
    <transform position={new Vector2(100, 60)}>
      <sprite textureId={BTN_TEXTURE} sourceSize={[128, 48]} />
      <clickable ref={btn} size={[128, 48]} />
    </transform>
  )
}

Props

size
VectorLike | SignalGetter<VectorLike>
required
Dimensions of the hit rectangle in pixels. There is no default — this prop is always required. Accepts Vector2, {x, y}, [x, y], or a single number for a square area. Reactive when a SignalGetter is passed.
disabled
boolean | SignalGetter<boolean>
When true, all pointer event checking is suspended. Events will not fire and the debug overlay turns grey. Reactive when a SignalGetter is passed. Defaults to false.
onClick
(position: Vector2) => void
Shorthand callback for the clicked event. Equivalent to useEvent(ref, 'clicked', fn). The position argument is the local coordinate relative to the node’s top-left corner.
onMouseEnter
() => void
Shorthand callback for the mouseEntered event. Fires once on the frame the pointer enters the hit area.
onMouseExit
() => void
Shorthand callback for the mouseExited event. Fires once on the frame the pointer leaves the hit area.
position
VectorLike | SignalGetter<VectorLike>
Local position offset. The hit rectangle starts at this position; size extends it to the right and down.
ref
NodeRef<PrimaryNode.Clickable>
A ref created by useRefNode(PrimaryNode.Clickable). Exposes the Clickable instance for runtime inspection.
children
Node[]
Optional child nodes rendered inside this clickable area.

Events

Subscribe with useEvent.
Event nameCallback signatureDescription
clicked(position: Vector2) => voidFires when a pointer press-and-release completes inside the area. position is local (relative to node’s top-left).
mouseEntered() => voidFires once on the first frame the pointer enters the hit area.
mouseExited() => voidFires once on the first frame the pointer leaves the hit area.
mouseOver(position: Vector2) => voidFires every frame the pointer is inside the area. position is local.
started() => voidFires once after the node finishes start().
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.

Debug visualisation

Set testOptions.showClickables = true to draw hit rectangles at runtime. Active areas render in yellow; disabled areas render in grey.
import { GameConfig } from 'tiny-engine'

GameConfig.testOptions.showClickables = true

Example — hover highlight with useSignal

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

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

function MenuButton({ onPress }: { onPress: () => void }) {
  const [hovered, setHovered] = useSignal(false)
  const brightness = useComputed(() => hovered() ? 1.35 : 1)

  return (
    <transform>
      <sprite
        textureId={BTN_TEXTURE}
        sourceSize={[128, 40]}
        displaySize={[128, 40]}
        brightness={brightness}
      />
      <clickable
        size={[128, 40]}
        onMouseEnter={() => setHovered(true)}
        onMouseExit={() => setHovered(false)}
        onClick={onPress}
      />
    </transform>
  )
}

Example — conditionally disabled button

import { useSignal } from 'tiny-engine/hooks'

function SubmitButton() {
  const [formValid, setFormValid] = useSignal(false)

  return (
    <transform>
      <sprite textureId={BTN_TEXTURE} sourceSize={[100, 32]} />
      <clickable
        size={[100, 32]}
        disabled={useComputed(() => !formValid())}
        onClick={() => submitForm()}
      />
    </transform>
  )
}
size has no default value. Omitting it is a runtime error. If your button dimensions change over time, pass a SignalGetter instead of patching the node directly.
Layer a Clickable as a sibling on top of your Sprite (same position and size) rather than making it a child of the sprite. This keeps the visual and interaction logic cleanly separated.
  • Transform — position the clickable in world space
  • Sprite — the visual element typically paired with a clickable
  • useSignal — reactive hover or disabled state
  • useComputed — derive brightness or color from hover state
  • useEvent — subscribe to clicked, mouseEntered, mouseExited

Build docs developers (and LLMs) love