# Custom sampling and fixed steps
Combine a time-sampled sine wave with a fixed-step state machine.

## APIs demonstrated

- [defineAnimation](/reference/functions/define-animation/) from `@pibbl/core`
- [stepper](/reference/functions/stepper/) from `@pibbl/core`
- [PibblAnimationOptions](/reference/types/canvas-runtime/) from `@pibbl/core`
- [PibblAnimationSampleInput](/reference/types/canvas-runtime/) from `@pibbl/core`
- [PibblStepperOptions](/reference/types/canvas-runtime/) from `@pibbl/core`

## Complete example

[Plain source](/minimal/animation/custom.tsx). Run as a browser module after the document body exists. TSX uses `jsx: "react-jsx"` and `jsxImportSource: "@pibbl/core"`.

```tsx
import {
  pibbl,
  Circle,
  useSignal,
  usePlayback,
  drive,
  parallel,
  defineAnimation,
  stepper,
  type PibblAnimationOptions,
  type PibblAnimationSampleInput,
  type PibblStepperOptions,
} from "@pibbl/core";

const canvas = document.createElement("canvas");
canvas.width = 420;
canvas.height = 200;
document.body.append(canvas);
const wave: PibblAnimationOptions<number> = {
  duration: 6000,
  sample({ initialValue, localTime }: PibblAnimationSampleInput<number>) {
    return initialValue + Math.sin(localTime / 350) * 60;
  },
};
type State = { x: number; velocity: number };
const integration: PibblStepperOptions<State, number> = {
  stepMilliseconds: 16,
  maxElapsedMilliseconds: 64,
  initial: (x) => ({ x, velocity: 70 }),
  step: (state, milliseconds) => ({
    ...state,
    x: state.x + (state.velocity * milliseconds) / 1000,
  }),
  read: (state) => state.x,
  done: (state) => state.x >= 360,
};
function Scene() {
  const y = useSignal(100);
  const x = useSignal(30);
  usePlayback(
    parallel(drive(y, defineAnimation(wave)), drive(x, stepper(integration))),
    { autoplay: true },
  );
  return <Circle style={{ radius: 15, left: x, top: y, fill: "#3369bb" }} />;
}
const controller = pibbl(canvas, <Scene />);
window.addEventListener("pagehide", () => controller.dispose(), { once: true });

```

## Usage notes

- Custom samples are seekable; stateful steppers integrate clamped elapsed time and are not generally seekable.

## Documentation version

Documentation built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.
