Pointer Events
Before this section, complete:
- Node Protocol — Factory function and init/draw
- Core Types — Path and Paint for visual feedback
- Control Flow — Conditionals for state handling
Build interactive controls, buttons, and gesture-driven interfaces using pointer event handlers.
Rive Context
Pointer handlers (pointerDown, pointerMove, pointerUp, pointerExit) are only called if you return them in the Node factory table. These events are local to the script's node, making them ideal for building self-contained interactive components.
Key concept: Use event:hit() to consume the event and stop propagation to nodes below.
Exercise 1: Press to Toggle Color ⭐⭐
Premise
pointerDown handles click events. Toggle state with 'not', update visuals, and call event:hit() to stop propagation.
By the end of this exercise, you will be able to Complete the pointerDown handler to toggle the button color between blue and orange on each press.
Use Case
This pattern shows up whenever you build behavior in Rive scripts.
Example scenarios:
- Debugging script behavior
- Driving animation logic
Setup
In Rive Editor:
-
Create the script:
- Assets panel →
+→ Script → Node Script - Name it
Exercise1_Exercise1PressToToggleColor
- Assets panel →
-
Attach and run:
- Attach to any shape and press Play
-
Open the Console:
- View → Console
Starter Code
--!strict
-- Toggle button color on press
export type ToggleButton = {
path: Path,
paint: Paint,
isPressed: boolean,
}
function init(self: ToggleButton): boolean
self.isPressed = false
self.path = Path.new()
self.path:moveTo(Vector.xy(-60, -30))
self.path:lineTo(Vector.xy(60, -30))
self.path:lineTo(Vector.xy(60, 30))
self.path:lineTo(Vector.xy(-60, 30))
self.path:close()
self.paint = Paint.with({ style = "fill", color = Color.rgb(80, 170, 255) })
print("Toggle button ready")
return true
end
function pointerDown(self: ToggleButton, event: PointerEvent)
-- TODO 1: Toggle isPressed using 'not'
-- self.isPressed = not self.isPressed
-- TODO 2: Update paint color based on isPressed
-- Use: self.isPressed and Color.rgb(255, 120, 80) or Color.rgb(80, 170, 255)
-- TODO 3: Call event:hit() to consume the event
print("Button toggled!")
print("ANSWER: toggled")
end
function draw(self: ToggleButton, renderer: Renderer)
renderer:drawPath(self.path, self.paint)
end
return function(): Node<ToggleButton>
return {
init = init,
draw = draw,
pointerDown = pointerDown,
path = late(),
paint = late(),
isPressed = false,
}
end
Assignment
Complete these tasks:
- Complete the pointerDown handler to toggle the button color between blue and orange on each press.
- Run the script and verify the console output
- Copy the
ANSWER:line into the validator
Expected Output
Console prints the relevant debug lines for this exercise.
ANSWER: <your result>
Verify Your Answer
Checklist
-
--!strictis at the top - All TODOs are replaced with working code
- Console output includes the
ANSWER:line
How it works:
- The
pointerDownhandler togglesisPressedstate - The paint color updates based on the current state
event:hit()consumes the event to prevent it from propagating
Exercise 2: Track Multiple Pointers ⭐⭐⭐
Premise
Each pointer has a unique event.id. Track them in a table: create on down, update on move, remove on up.
By the end of this exercise, you will be able to Complete the pointer handlers to track multiple touch points simultaneously.
Use Case
This pattern shows up whenever you build behavior in Rive scripts.
Example scenarios:
- Debugging script behavior
- Driving animation logic
Setup
In Rive Editor:
-
Create the script:
- Assets panel →
+→ Script → Node Script - Name it
Exercise2_Exercise2TrackMultiplePointers
- Assets panel →
-
Attach and run:
- Attach to any shape and press Play
-
Open the Console:
- View → Console
Starter Code
--!strict
-- Track multiple pointers by their unique IDs
type PointerState = {
position: Vector,
}
export type MultiTouch = {
pointers: { [number]: PointerState },
pointerCount: number,
}
function init(self: MultiTouch): boolean
self.pointers = {}
self.pointerCount = 0
print("Multi-touch tracker ready")
return true
end
function pointerDown(self: MultiTouch, event: PointerEvent)
-- TODO 1: Create a new entry in self.pointers using event.id as key
-- Store { position = event.position }
-- TODO 2: Increment pointerCount and print the pointer number
-- TODO 3: If pointerCount >= 2, print the answer
-- TODO 4: Call event:hit()
end
function pointerMove(self: MultiTouch, event: PointerEvent)
-- TODO 5: Get the pointer from self.pointers[event.id]
-- If it exists, update its position
local pointer = self.pointers[event.id]
if pointer then
pointer.position = event.position
end
event:hit()
end
function pointerUp(self: MultiTouch, event: PointerEvent)
-- TODO 6: Remove the pointer by setting self.pointers[event.id] = nil
-- TODO 7: Decrement pointerCount
-- TODO 8: Call event:hit()
end
function draw(self: MultiTouch, renderer: Renderer)
-- Pointer positions can drive visuals here
end
return function(): Node<MultiTouch>
return {
init = init,
draw = draw,
pointerDown = pointerDown,
pointerMove = pointerMove,
pointerUp = pointerUp,
pointers = {},
pointerCount = 0,
}
end
Assignment
Complete these tasks:
- Complete the pointer handlers to track multiple touch points simultaneously.
- Run the script and verify the console output
- Copy the
ANSWER:line into the validator
Expected Output
Console prints the relevant debug lines for this exercise.
ANSWER: <your result>
Verify Your Answer
Checklist
-
--!strictis at the top - All TODOs are replaced with working code
- Console output includes the
ANSWER:line
How it works:
- Each pointer has a unique
event.id pointerDowncreates a new entry in thepointerstablepointerMoveupdates the position for that specific pointerpointerUpremoves the pointer from tracking
Key Takeaways
- Pointer events are local to the script's node
- Return handler functions in the factory table to receive events
- Use
event:hit()to consume events and stop propagation - Track pointers by their unique
event.idfor multi-touch support
Next Steps
- Continue to Dynamic Instantiation
- Need a refresher? Review Quick Reference