---
title: ClockActor
description: A stopwatch whose elapsed time is computed from the frame, from @motionactor/primitives.
---

`ClockActor` counts frames while it runs. It stores only when it started and what it had
counted before, and works out the elapsed time from the frame being resolved, so frame 105
reads the same whether playback got there by playing or by seeking.

```ts twoslash title="stopwatch.ts"
import { child, createScene, derived, LayoutActor } from "@motionactor/core";
import { ClockActor } from "@motionactor/primitives";

class Stopwatch extends LayoutActor {
  clock = child(ClockActor);
  label = derived(() => this.clock.elapsedSeconds().toFixed(1));
}

const compiled = createScene(function* (ctx) {
  const watch = ctx.spawn(Stopwatch);
  yield* watch.clock.start(2);
  yield* watch.clock.pause(1);
  yield* watch.clock.resume(1);
  return { watch };
}).build({ viewport: { width: 1920, height: 1080 }, fps: 30 });

compiled.at(60).scene.watch?.label; // "2.0"
compiled.at(75).scene.watch?.label; // "2.0", paused
compiled.at(105).scene.watch?.label; // "2.5"
```

## Commands

Each command changes the clock at the cursor and then waits its `duration` in seconds, 0 by
default. `start(2)` reads as "start, and let it run for two seconds".

| Command | Does |
| --- | --- |
| `start(duration?)` | Starts counting. On a running clock it does nothing |
| `pause(duration?)` | Stops counting and keeps the count |
| `resume(duration?)` | Counts on from the kept count. The same as `start` |
| `reset(duration?)` | Stops the clock and zeroes it |

## Values

| Field | |
| --- | --- |
| `elapsedFrames` | Frames counted |
| `elapsedSeconds` | `elapsedFrames` over the build's frame rate |
| `elapsedMilliseconds` | The same, in milliseconds |
| `running` | Whether it is counting |

The elapsed values are [derived](/docs/reactivity/derived), so another actor's derived value or a
renderer can read them like any signal. A countdown is `total - clock.elapsedSeconds()`.

Past the scene's last frame a running clock reads as it did on that frame, because every
later frame resolves as the last one. It never reads wall-clock time.

`ClockActor` measures time and runs nothing. To repeat work, use
[`runtime.loop`](/docs/runtime/scene-orchestration#inside-an-actor). To wait, use `ctx.wait`.
