import { defineBehavior, FollowPath, Path, Pile, Spin, Trip, usePath, useTrip, useTripStatus, Vehicle } from "@apricot/react";
import type { TripHandle, TripState, TripStatus, VehicleOptions, VehicleState } from "@apricot/react";For shared values, useFrame and useAnimatable, see Hooks.
Spin#
Spins its children.
| Prop | Type | Default | Description |
|---|---|---|---|
speed |
number or shared value |
1 |
Radians per second |
axis |
Vec3 or shared value |
[0, 1, 0] |
The axis to spin around |
children |
ReactNode |
defineBehavior(definition)#
Turns per-frame logic into a component that wraps children (Spin is built with it). Returns a component whose props are the keys of defaults (each plain or shared) plus children.
| Field | Type | Description |
|---|---|---|
name |
string |
Display name and the wrapping group's name |
defaults |
object |
Every prop with its default value |
frame |
(object, props, state) => boolean | undefined |
Runs before each frame on the wrapping group. state is { time, delta, frame }. Return true while still moving |
See Custom geometry and behaviors.
Vehicle#
Drives its children like a toy car on the ground plane. Renders only while the car moves or an input is non-zero. Options are read once, at mount.
| Prop | Type | Default | Description |
|---|---|---|---|
throttle |
number or shared value |
0 |
−1 (reverse, brake) to 1 (full throttle) |
steer |
number or shared value |
0 |
−1 (left) to 1 (right) |
start |
{ x?, z?, heading? } |
{ 0, 0, 0 } |
Start place; heading in radians, 0 faces +z |
onUpdate |
(state: VehicleState) => void |
After each simulated frame, on the JS thread | |
ref |
Ref<SceneObject> |
The moving group (a <FollowCamera> target) |
|
children |
ReactNode |
The car. Descendants named wheel_f… steer and spin; wheel_r… spin |
|
maxSpeed |
units/s | 12 |
Top speed forwards |
maxReverse |
units/s | 4 |
Top speed in reverse |
acceleration |
units/s² | 9 |
At full throttle |
braking |
units/s² | 20 |
Throttle against the motion |
drag |
units/s² | 3 |
Coasting |
wheelBase |
units | 1.4 |
Distance between the axles: shorter turns tighter |
maxSteer |
radians | 0.6 |
Largest front-wheel angle |
steerSpeed |
per second | 8 |
How fast the wheels reach the requested angle |
wheelRadius |
units | 0.3 |
For the wheels' spin |
bounds |
[minX, minZ, maxX, maxZ] |
none | Keeps the car inside this box |
VehicleState: { x, z, heading, speed, steer, wheelSpin }. heading and steer in radians (positive steer is right); speed signed, units per second; wheelSpin accumulated radians.
Pile#
Drops copies of its children from above the visible area; they collide, bounce and heap up. Each kind is one draw call. The scene stops rendering once the pile rests.
| Prop | Type | Default | Description |
|---|---|---|---|
count |
number | required | How many objects in total |
duration |
seconds | 5 |
Over how long they drop |
bounds |
{ min: Vec3, max: Vec3 } |
the visible area | The box to fill; floor at min[1]. Changing it moves the walls without restarting |
depth |
units | 0.5 |
Half the thickness of the default area |
scale |
[min, max] |
[0.9, 1.1] |
Random size range, relative to each child |
speed |
units/s | 2 |
Downward speed on entry |
spin |
radians/s | 4 |
Largest initial tumble |
seed |
number | 1 |
Random seed |
physics |
SphereWorldOptions |
see below | Solver settings |
onSettled |
() => void |
Everything dropped and rests | |
children |
ReactNode |
required | Templates: one kind each, meshes only. Their own transforms are ignored. Collision radius: userData.radius, else the bounding sphere |
physics: gravity ([0, -15, 0]), friction (0.6, floor only), bodyFriction (0.15), damping (0.05), contactDamping (4), restSpeed (0.12), settleTime (0.4 s), maxSpeed (40), iterations (2), maxSubstep (1/120 s).
The pile restarts when an option changes (compared by value). Change its key to replay.
Paths#
usePath(points, options?)#
Returns a Path: a smooth curve through points (Vec3[]). Rebuilt only when the values change.
| Option | Default | Description |
|---|---|---|
closed |
false |
Joins the end back to the start |
tension |
0.5 |
0–1: how tightly the curve hugs the points. 0.5 is smooth with no overshoot |
new Path(points, options) builds one outside React.
Path#
| Member | Returns | Description |
|---|---|---|
length |
number | Total length |
pointAt(distance, target?) |
Vector3 |
The point at that distance |
tangentAt(distance, target?) |
Vector3 |
Unit direction of travel there |
place(object, distance, direction = 1) |
Moves and turns an object onto the path, +z forward, +y up. −1 faces backwards | |
every(spacing, start = 0) |
number[] |
Distances every spacing units |
distanceTo(point, samples = 400) |
number | The distance along the path closest to a point |
clamp(distance) |
number | Wraps around a closed path, clamps to the ends of an open one |
Trips#
useTrip(options)#
Runs a vehicle along stops: speeds up, cruises, brakes exactly onto each stop, waits, goes on. Time-based, exact at any frame rate, and it keeps its place while the app sleeps. Works outside <Scene>.
| Option | Type | Default | Description |
|---|---|---|---|
stops |
number[] |
required | Distances of the stops along the path, in order |
path |
Path |
Gives "loop" trips their length |
|
speed |
units/s | 20 |
Top speed |
acceleration |
units/s² | 1.2 |
|
deceleration |
units/s² | the acceleration | |
dwell |
seconds | 8 |
Wait at each stop |
pattern |
"shuttle" | "loop" | "once" |
"shuttle" |
After the last stop: run back, go on round to the first, or stay |
start |
seconds | 0 |
Seconds into the trip at mount. 0 is waiting at the first stop |
clock |
() => number |
device clock | Seconds now. Pass a server clock to sync devices |
onArrive, onDepart |
(stop: number) => void |
With the stop's index |
Returns a TripHandle: { trip, elapsed(), state() }. new Trip(options) (with length for loops) gives the timeline outside React: trip.at(seconds) returns a TripState.
TripState#
| Field | Description |
|---|---|
distance |
Along the path |
speed |
Units per second (0 at a stop) |
direction |
1 forward along the path, -1 back |
stopped |
Waiting at a stop |
stop |
Index of the stop it is at, or last left |
nextStop |
Index of the stop it is heading for |
eta |
Seconds until the next stop (moving) or until it leaves (stopped) |
useTripStatus(trip, every = 1)#
Returns a TripStatus: TripState plus seconds (eta rounded up), refreshed every every seconds by a timer. It re-renders its component every second: use it in a small component of its own.
FollowPath#
Puts its children on a path, facing along it (+z forward).
| Prop | Type | Default | Description |
|---|---|---|---|
path |
Path |
required | |
distance |
number or shared value |
0 |
Distance along the path |
trip |
TripHandle |
Or ride a trip: distance and direction come from it | |
offset |
units | 0 |
Ahead (+) or behind (−) of that distance: one per car of a train |
orient |
boolean | true |
Face along the path; false keeps the children's rotation |
ref |
Ref<SceneObject> |
The moving group | |
children |
ReactNode |