# useGlLane

> What a lane drawn by WebGL on one canvas needs: the canvas placed on the stretch of the lane the view shows, drawn again when its inputs change, it resizes, the view scrolls or the theme changes, and let go of when it leaves.

```bash
npx shadcn@latest add @audio-ui/use-gl-lane
```

```ts
import { sameSamples, visibleClips, OVERSCAN, groundOf, hasWebGL2, /* … */ } from "@/hooks/use-gl-lane";
```

- Files: `hooks/use-gl-lane.ts`
- Depends on: `arrangement`; npm: nothing
- Used by: `block-audio-editor`, `clip-spectrogram`, `waveform-lane`

| Export | Kind | What it is |
| --- | --- | --- |
| `LaneSamples` | interface | A recording's samples, mixed to one: how many frames it holds, and a reader of the frames from `from` to `to`. |
| `LaneClip` | interface | A clip of a lane to draw: where it starts, what it reads and at what level. |
| `sameSamples` | function | Whether two readings are the same samples: a reader may hand out a new view of the same memory each time, which is not new data to upload. |
| `VisibleClip` | interface | A clip the view shows: its part of the canvas in CSS px from the canvas' left, the frames of its recording it reads there, and its samples. |
| `visibleClips` | function | The clips of a lane the view shows, each with its part of the canvas and the frames it reads there, and their samples read together. |
| `OVERSCAN` | const | The pixels drawn past each edge of the view, so a scroll shows them at once. |
| `groundOf` | function | The nearest background that is not transparent, from `element` up: what a picture's silence lies over. |
| `hasWebGL2` | function | Whether this browser can draw with WebGL 2: the lanes that need it say no, and the page draws them another way. |
| `placeLane` | function | Sizes the canvas to the stretch of its lane the view shows, and gives that stretch in CSS px from the lane's left with the device pixel ratio, or hides the canvas when none shows. |
| `GlLaneContext` | interface | What a lane hands its painter and its listeners. |
| `useGlLane` | function | What a lane drawn by WebGL on one canvas needs: the canvas placed on the stretch of the lane the view shows, drawn again when its `inputs` change, the lane resizes, the view scrolls a good way or the theme changes, and let go of when it leaves. |

## Usage

A lane of clips drawn on the GPU is one canvas in the lane's box, sized to the stretch the view shows, with every clip in its own viewport of one WebGL context: a browser keeps some sixteen contexts and drops the oldest past that, so a canvas a clip would lose its picture once a sound is cut into enough pieces. `useGlLane` is what the two such lanes of the registry share, [`WaveformLane`](/docs/components/base/waveform-lane) and [`SpectrogramLane`](/docs/components/base/clip-spectrogram), and what a lane of your own over another renderer would use.

```tsx
import { useGlLane, placeLane, visibleClips } from "@/hooks/use-gl-lane";

const ref = useGlLane({
  create: () => ({ gone: false, renderers: new Map() }), // what the lane keeps between paints
  destroy: (held) => { /* let go of what create made */ },
  inputs, // memoized: a new value draws again
  paint: async ({ body, canvas, held, inputs, view }) => {
    const { clips, zoom } = inputs();
    const placed = placeLane(canvas, body, view); // null when no part of the lane shows
    if (!placed) return false;
    const visible = await visibleClips(clips, placed, zoom); // each with its x, width and frames
    // draw each into its viewport; return true while some of it is not yet whole
    return false;
  },
});

<canvas className="absolute inset-y-0" ref={ref} />;
```

`placeLane` sizes the canvas to what the view shows and gives where it starts, and `visibleClips` the clips of the lane the view shows with the frames each reads there and their samples. `sameSamples` tells whether a reader handed out the same memory again, so it is not uploaded twice, and `hasWebGL2` whether this browser can draw this way at all: a page draws the lane another way when it cannot.
