GGenomics UI
Components/Foundation

Use Viewport

@genomics/use-viewport

Pan and zoom, shared across an axis.

Preview

chr7
⌘/ctrl + scroll to zoom · drag to pan · +/− and arrows when focused
40,000,00060,000,000 · 20,000,000 bp
a second surface on the same axis
linked through coordinate-link's viewport channel — no props between them
0159,345,973 · 159,345,973 bp

The two surfaces above use different axis names, so they move independently. Give them the same name and they lock together.

About

Pan and zoom existed in two of forty viewers — not because the rest didn't want it, but because the plumbing is fiddly (non-passive wheel, pointer capture, zoom anchored under the cursor, clamping that doesn't stick at the edges) and nobody wanted to write it a third time. The larger problem was that where it existed it was private: coordinate-link shared which residue was selected but not which window was being looked at, so an ideogram above a track viewer could not follow it. This writes through a viewport channel on the substrate, so every viewer passing the same axis string moves together, and an overview strip opts out with linked: false to draw its locator box instead.

Usage

import { useViewport } from "@/components/ui/use-viewport"

const vp = useViewport({ axis: "chr7", bounds: [0, 159_345_973] })

<div ref={vp.ref} {...vp.gestureProps} tabIndex={0}>…</div>
Source: components/ui/use-viewport.ts