---
title: Node
---

Node scripts can be used to render shapes, images, text, artboards, and more.
A scripted node can be attached to any Node and is rendered
in the local transform space of the hosting Node.

For more information, see [Node Scripts](/scripting/protocols/node-scripts).


## Methods

### `init`

{/* init: ((self: T, context: Context) -> boolean)? */}
<div class="signature">
```lua
init(self: T, context: Context) -> boolean
```
</div>

Called once when the node is created. Returns true if initialization
succeeds.

For a more complete example using `init`, see [Instantiating Components](/scripting/protocols/node-scripts#instantiating-components).
```lua highlight={5,6,7,12}
-- Define the script's data and inputs.
type MyNode = {}

-- Called once when the script initializes.
function init(self: MyNode, context: Context): boolean
  return true
end

-- Return a factory function that Rive uses to build the Node instance.
return function(): Node<MyNode>
  return {
    init = init
  }
end
```


### `advance`

{/* advance: ((self: T, seconds: number) -> boolean)? */}
<div class="signature">
```lua
advance(self: T, seconds: number) -> boolean
```
</div>

Optional per-frame update. Returns true if the node should continue
receiving advance calls.

For a more complete example using `advance`, see [Fixed-step Advanced](/scripting/protocols/node-scripts#fixed-step-advance).
```lua highlight={6,7,8,13}
-- Define the script's data and inputs.
type MyNode = {}

-- Called every frame to advance the simulation.
-- 'seconds' is the elapsed time since the previous frame.
function advance(self: MyNode, seconds: number): boolean
  return false
end

-- Return a factory function that Rive uses to build the Node instance.
return function(): Node<MyNode>
  return {
    advance = advance,
  }
end
```


### `update`

{/* update: (self: T) -> ()? */}
<div class="signature">
```lua
update(self: T) -> ()
```
</div>

Called when an input value changes.
```lua highlight={5,6,7,12}
-- Define the script's data and inputs.
type MyNode = {}

-- Called when any input value changes.
function update(self: MyNode)
  print('An script input value has changed.')
end

-- Return a factory function that Rive uses to build the Node instance.
return function(): Node<MyNode>
  return {
    update = update,
  }
end
```


### `draw`

{/* draw: ((self: T, renderer: Renderer) -> ())? */}
<div class="signature">
```lua
draw(self: T, renderer: Renderer) -> ()
```
</div>

Called to render the node using the provided [Renderer](/scripting/api-reference/renderer/renderer).

For a more complete example using draw, see [Instantiating Components](/scripting/protocols/node-scripts#instantiating-components).
```lua highlight={5,10}
-- Define the script's data and inputs.
type MyNode = {}

-- Called every frame (after advance) to render the content.
function draw(self: MyNode, renderer: Renderer) end

-- Return a factory function that Rive uses to build the Node instance.
return function(): Node<MyNode>
  return {
    draw = draw,
  }
end
```


### `drawCanvas`

{/* drawCanvas: ((self: T) -> ())? */}
<div class="signature">
```lua
drawCanvas(self: T) -> ()
```
</div>

Called during the drawCanvases pass (before draw).
All canvas beginFrame/beginRenderPass calls must happen here.


### `pointerDown`

{/* pointerDown: (self: T, event:PointerEvent) -> ()? */}
<div class="signature">
```lua
pointerDown(self: T, event: PointerEvent) -> ()
```
</div>

Pointer event down handler.

```lua
function handlePointerDown(self: MyGame, event: PointerEvent)
  print('Pointer Position: ', event.position.x, event.position.y)

  event:hit()
end

return function(): Node<MyGame>
    return {
        init = init,
        advance = advance,
        draw = draw,
        pointerDown = handlePointerDown,
    }
end
```


### `pointerMove`

{/* pointerMove: (self: T, event:PointerEvent) -> ()? */}
<div class="signature">
```lua
pointerMove(self: T, event: PointerEvent) -> ()
```
</div>

Pointer event move handler.

```lua
function handlePointerMove(self: MyGame, event: PointerEvent)
  print('Pointer Position: ', event.position.x, event.position.y)

  event:hit()
end

return function(): Node<MyGame>
    return {
        init = init,
        advance = advance,
        draw = draw,
        pointerMove = handlePointerMove,
    }
end
```


### `pointerUp`

{/* pointerUp: (self: T, event:PointerEvent) -> ()? */}
<div class="signature">
```lua
pointerUp(self: T, event: PointerEvent) -> ()
```
</div>

Pointer event up handler.
```lua
function handlePointerUp(self: MyGame, event: PointerEvent)
  print('Pointer Position: ', event.position.x, event.position.y)

  event:hit()
end

return function(): Node<MyGame>
    return {
        init = init,
        advance = advance,
        draw = draw,
        pointerUp = handlePointerUp,
    }
end
```


### `pointerExit`

{/* pointerExit: (self: T, event:PointerEvent) -> ()? */}
<div class="signature">
```lua
pointerExit(self: T, event: PointerEvent) -> ()
```
</div>

Pointer event exit handler.
```lua
function handlePointerExit(self: MyGame, event: PointerEvent)
  print('Pointer Position: ', event.position.x, event.position.y)

  event:hit()
end

return function(): Node<MyGame>
    return {
        init = init,
        advance = advance,
        draw = draw,
        pointerExit = handlePointerExit,
    }
end
```


