Skip to main content

rc-virtual-canvas

Scrollable virtual canvas for rendering large coordinate-space content.

Overlays a transparent scrollable div on top of a slotted <canvas> element, dispatching rc-virtual-canvas-render events with the current viewport and content rectangles. Consumers draw only what is visible.

Package
@rcarls/rc-virtual-canvas
Element
<rc-virtual-canvas>
Native dependency
Requires a direct child native canvas
State model
Virtual scroll geometry
Main events
rc-virtual-canvas-pointerrc-virtual-canvas-render

Installation​

npm install @rcarls/rc-webcomponents@next
import '@rcarls/rc-webcomponents/rc-virtual-canvas/define';

Usage​

Place a <canvas> inside the component, set content-width and content-height to the size of the whole virtual surface, and draw the visible part on each rc-virtual-canvas-render event.

<rc-virtual-canvas content-width="4000" content-height="3000" style="width: 800px; height: 600px">
<canvas aria-label="Floor plan" width="800" height="600"></canvas>
</rc-virtual-canvas>

Live demo​

The native <canvas> must be a direct child of rc-virtual-canvas. Keeping it in light DOM preserves the consumer's drawing surface and accessible fallback content before and after the custom element upgrades.

Accessibility​

A canvas is a bitmap with no semantics of its own, so the component adds none. When the drawing carries information or interaction:

  • Name the <canvas> with aria-label or aria-labelledby.
  • Provide the same information outside the canvas, such as in a table, hidden visually rather than with display: none.
  • Give interactive content, such as hit-testing or dragging, keyboard equivalents on a separate focusable element.

Theming​

The default demo mode shows the component without a package theme. Use the shared preview controls on this page to compare inherited, light, and dark color schemes or to apply the optional Material theme only inside the demo frames.

API​

Properties​

PropertyMarkupTypeDefaultDescription
contentWidthcontent-widthUnknownNot specifiedPixel width of the virtual content
contentHeightcontent-heightUnknownNot specifiedPixel height of the virtual content
autoResizeCanvasauto-resize-canvasbooleantrueWhen true, keep the slotted canvas backing store aligned to the viewport.
renderModerender-modeRCVirtualCanvasRenderMode'continuous'Controls when render events are dispatched.
imageRenderingimage-renderingRCVirtualCanvasImageRendering'auto'Convenience image-rendering value applied to the slotted canvas.
canvasScaleXJS property onlynumberNot specifiedRatio of canvas backing-store pixels to CSS pixels along the x-axis. Use as the x-scale factor in `ctx.scale()` to draw at CSS pixel resolution. When `autoResizeCanvas` is true, CSS zoom changes this ratio along with the backing-store resolution.
canvasScaleYJS property onlynumberNot specifiedRatio of canvas backing-store pixels to CSS pixels along the y-axis. Use as the y-scale factor in `ctx.scale()` to draw at CSS pixel resolution. CSS zoom can make this ratio differ from `devicePixelRatio`.

Methods​

MethodDescription
getViewRect()Returns a frozen snapshot of the current viewport rectangle. Safe to keep between frames — the returned object will not be mutated by future scroll or resize work.
scrollToContent(x: number, y: number, options: ScrollOptions)Scrolls so the content coordinate is at the viewport origin.
centerOnContent(x: number, y: number, options: ScrollOptions)Scrolls so the content coordinate is centered in the viewport.
clientToContent(clientX: number, clientY: number)Converts browser client coordinates to CSS-pixel content coordinates. Canvas backing-store resolution does not change content coordinates.
contentToClient(x: number, y: number)Converts content coordinates back to browser client coordinates.
requestRender(reason: RCVirtualCanvasRenderReason)Queues a render event on the next animation frame. Required when `renderMode` is `'manual'`. In other modes the component schedules renders automatically; calling this with reason `'animation-frame'` is a no-op when `renderMode` is `'viewport-change'`.

Events​

EventDetail typeDescription
rc-virtual-canvas-pointerCustomEventFires pointer/mouse input mapped to virtual content coordinates.
rc-virtual-canvas-renderCustomEventFires with viewport data when the canvas should redraw.

Slots​

NameDescription
(default)The HTMLCanvasElement
overlayOptional viewport-positioned content rendered inside the scroll container above the canvas.

CSS Custom Properties​

PropertyDefaultDescription
--rc-virtual-canvas-scrollbar-widththin`scrollbar-width` of the internal scroll container.
--rc-virtual-canvas-scrollbar-sizeautoWebKit scrollbar thickness.
--rc-virtual-canvas-scrollbar-thumb-backgroundButtonFaceWebKit scrollbar thumb color.
--rc-virtual-canvas-scrollbar-button-backgroundButtonFaceWebKit scrollbar button color.
--rc-virtual-canvas-scrollbar-track-backgroundCanvasWebKit scrollbar track color.
--rc-virtual-canvas-image-renderingauto`image-rendering` applied to the slotted canvas; kept in sync with the `imageRendering` property.

CSS Parts​

PartDescription
scrollerInternal scroll container that owns the virtual content scroll range.
overlayViewport-positioned overlay container rendered inside the scroll container.

Read-only properties​

These are computed getters exposed for rendering convenience. They do not appear in the generated API table above.

PropertyTypeDescription
canvasScaleXnumberRatio of backing-store pixels to local CSS pixels along the x-axis. CSS zoom can make it differ from devicePixelRatio. Use it to scale the drawing context to CSS pixel space.
canvasScaleYnumberRatio of canvas backing-store pixels to CSS pixels along the y-axis.

Zoom and scale​

rc-virtual-canvas is a pan-only viewport. It does not manage a content scale factor. Zoom (pinch-to-zoom, scroll-to-zoom) is the consumer's responsibility and should be applied by:

  • Scaling the canvas context (ctx.scale(zoom, zoom)) before drawing, and
  • Adjusting contentWidth and contentHeight to reflect the scaled content dimensions so the scrollable area matches.

CSS zoom on the component or an ancestor changes the canvas's rendered size and backing-store resolution. clientToContent() and contentToClient() continue to use CSS-pixel content coordinates; canvasScaleX and canvasScaleY report the backing-store pixels per local CSS pixel.