Pan Zoom
A viewport that pans and zooms its content: an image, an SVG diagram, a floor plan or a board.
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
min-zoom | number | 'fit' | DEFAULT_MIN_ZOOM | Least zoom: a number, or fit to stop zooming out at the fitted view (for image previews). |
max-zoom | CustomEvent | DEFAULT_MAX_ZOOM | Greatest zoom (1 = 100%). |
zoom-step | CustomEvent | DEFAULT_ZOOM_STEP | The factor of one button press or key press. |
fit | PanZoomFit | contain | The first view, and the view reset() and the 0 key go back to: contain shows the whole content, cover fills
the box, width fits the width and starts at the top, none starts at 100% in the centre. A fitted view never
zooms past 100%. |
bounds | PanZoomBounds | content | content keeps the content in view (content smaller than the box stays centred); none is a free canvas. |
gestures | PanZoomGestures | cooperative | What the wheel and one finger do. cooperative: they scroll the page, and Ctrl/⌘ + wheel, a pinch, two fingers
or a mouse drag move the view. pan: the wheel pans and Ctrl/⌘ + wheel zooms. zoom: the wheel zooms to the
pointer (and one finger pans). none: no pointer gesture at all, not even Space + drag or a middle-button drag;
only the buttons, the minimap, the keys and the methods move the view. |
controls | boolean | false | Draws the toolbar: zoom out, the zoom percent, zoom in and fit. |
minimap | boolean | false | Draws the minimap, which shows while the content overflows. |
no-inertia | boolean | false | A released drag stops at once instead of gliding. |
no-double-click-zoom | boolean | false | A double-click (or double tap) no longer zooms in. |
no-keyboard | boolean | false | The viewport is not a tab stop and has no role; the component around it handles the keys. |
label | string | — | Accessible name of the viewport. |
zoom | number | — | The current zoom (1 = 100%). Setting it zooms around the centre, without an event. |
view | PanZoomView | — | The view: { x, y, zoom }, where x and y are the content point at the top-left corner. Setting it (or the
view attribute, as JSON) moves the view without an event, so a saved view comes back with no jump, even from a
server render. |
Slots
| Name | Description |
|---|---|
(default) | The content, laid out at its natural size. Give it a size: an <img> or <svg> with width and height. |
minimap | Custom minimap content, drawn at the content's aspect ratio. |
controls | Extra buttons appended to the toolbar. |
Events
| Name | Type | Description |
|---|---|---|
view-settle | CustomEvent<PanZoomViewDetail> | The same detail, once when a move and its glide end. Does not bubble. |
view-change | CustomEvent<PanZoomViewDetail> | { x, y, zoom, reason } once per frame while the view moves. x and y are the content point at the top-left corner; reason is gesture, wheel, keyboard, controls, fit, resize or api. Not fired when view or zoom is set. Does not bubble. |
CSS parts
Shadow DOM styling hooks used with ::part(name). Prefer CSS custom properties when they cover the change.
| Name | Description |
|---|---|
viewport | The pannable area: the tab stop, with the group role. |
content | The wrapper the content is laid out in, and moved by the transform. |
grid | The dot grid behind the content. |
controls | The toolbar container: the zoom buttons and readout, with the controls slot's extra buttons placed inside it after them. |
button | Each toolbar button. |
readout | The zoom percent button. |
minimap | The minimap box: it holds the minimap slot when one is assigned, else a drawn copy of the content as fallback. |
minimap-frame | The viewport rectangle in the minimap. |
hint | The hint a plain wheel shows in cooperative mode. |
CSS custom properties
Grouped by semantic target and state from --c2-<component>__<target>__<state>--<property>. Click a group to collapse it; click a name to copy it.
| Name | Type | Default | Description |
|---|---|---|---|
--c2-pan-zoom--width | length | 100% | Width of the viewport; it is kept even as a flex item, which would otherwise shrink it to nothing. |
--c2-pan-zoom--height | pixel | 400px | Height of the viewport. |
--c2-pan-zoom--background | background | #fafafa | |
--c2-pan-zoom--border | border | 1px solid #e4e4e7 | |
--c2-pan-zoom--border-radius | border-radius | 8px | |
--c2-pan-zoom--cursor | cursor | grab | |
--c2-pan-zoom--transition-duration | duration | 200ms | Duration of the moves made by the buttons, the keys and the methods. Gestures never animate. |
--c2-pan-zoom--fit-padding | pixel | 24px | Space a fitted view leaves round the content. |
--c2-pan-zoom__dragging--cursor | cursor | grabbing | While dragging, and while Space is held. |
--c2-pan-zoom__grid--display | display | none | block draws a dot grid that scales with the zoom. |
--c2-pan-zoom__grid--color | color | #d4d4d8 | |
--c2-pan-zoom__grid--gap | pixel | 20px | Gap between the dots at 100%. |
--c2-pan-zoom__focus--outline | outline | 2px solid rgba(2, 101, 220, 0.4) | Focus ring of the viewport, drawn inside its edge, and of the toolbar buttons. |
--c2-pan-zoom__controls--inset | inset | auto 12px 12px auto | Where the toolbar sits: the bottom-right corner. |
--c2-pan-zoom__controls--background | background | #ffffff | |
--c2-pan-zoom__controls--border | border | 1px solid #e4e4e7 | |
--c2-pan-zoom__controls--border-radius | border-radius | 8px | |
--c2-pan-zoom__controls--box-shadow | box-shadow | 0 8px 24px rgba(24, 24, 27, 0.08) | |
--c2-pan-zoom__controls--color | color | #18181b | Icons and the zoom percent. |
--c2-pan-zoom__controls--font-size | pixel | 12px | |
--c2-pan-zoom__button--size | pixel | 28px | |
--c2-pan-zoom__button--border-radius | border-radius | 6px | |
--c2-pan-zoom__button__hover--background | background | #f4f4f5 | |
--c2-pan-zoom__button__disabled--opacity | opacity | 0.38 | Zoom in and zoom out at the zoom limits. |
--c2-pan-zoom__minimap--inset | inset | auto auto 12px 12px | Where the minimap sits: the bottom-left corner. |
--c2-pan-zoom__minimap--width | pixel | 160px | |
--c2-pan-zoom__minimap--max-height | pixel | 120px | Tall content narrows the minimap to stay within this. |
--c2-pan-zoom__minimap--background | background | #ffffff | |
--c2-pan-zoom__minimap--border | border | 1px solid #e4e4e7 | |
--c2-pan-zoom__minimap--border-radius | border-radius | 6px | |
--c2-pan-zoom__minimap--box-shadow | box-shadow | 0 8px 24px rgba(24, 24, 27, 0.08) | |
--c2-pan-zoom__minimap-content--background | background | #e4e4e7 | The plain rectangle drawn for content the minimap cannot copy. |
--c2-pan-zoom__minimap-frame--border | border | 2px solid #0265dc | The viewport rectangle. |
--c2-pan-zoom__minimap-frame--background | background | rgba(2, 101, 220, 0.2) | |
--c2-pan-zoom__hint--background | background | #18181b | |
--c2-pan-zoom__hint--color | color | #fafafa | |
--c2-pan-zoom__hint--font-size | pixel | 14px | |
--c2-pan-zoom__hint--border-radius | border-radius | 8px | |
--c2-pan-zoom__scrim--background | background | rgba(9, 9, 11, 0.45) | Behind the hint. |
Text and languages
The text the component shows, in English. It shows another language when the app adds one with addTranslations, under pan-zoom, and the nearest lang asks for it; any message not translated stays in English. {0}, {1}… stand for the values a message carries. Languages guide.
| Key | English | Values |
|---|---|---|
roleDescription | zoomable view | — |
keyHelp | Arrow keys to pan, plus and minus to zoom, 0 to fit. | — |
controls | Zoom controls | — |
zoomIn | Zoom in | — |
zoomOut | Zoom out | — |
fitView | Fit to view | — |
resetZoom | Zoom {0}, reset to {1} | {0} percent {1} actual |
zoomed | Zoom {0} | {0} percent |
wheelHint | Use {0} + scroll to zoom | {0} key |
ctrlKey | Ctrl | — |
touchHint | Use two fingers to move the view | — |