Scroll Plugin
The Scroll Plugin handles page layout, virtualization, and navigation logic. It provides the <Scroller /> component, which efficiently renders only the visible pages dynamically based on the current viewport position, and the useScroll store for programmatic navigation.
This plugin works in tandem with the Viewport Plugin and supports multi-document layouts, managing independent scroll states and strategies (vertical/horizontal) for each open document.
Installation
This plugin depends on the Viewport plugin.
npm install @embedpdf/plugin-scroll @embedpdf/plugin-viewportRegistration
Import ScrollPluginPackage and add it to your plugin configuration.
import { createPluginRegistration } from '@embedpdf/core'
// ... other imports
import { ViewportPluginPackage } from '@embedpdf/plugin-viewport/svelte'
import { ScrollPluginPackage, ScrollStrategy } from '@embedpdf/plugin-scroll/svelte'
const plugins = [
// ... other essential plugins
createPluginRegistration(DocumentManagerPluginPackage, { /* ... */ }),
createPluginRegistration(RenderPluginPackage),
// Register dependencies first
createPluginRegistration(ViewportPluginPackage),
// Register and configure the scroll plugin
createPluginRegistration(ScrollPluginPackage, {
defaultStrategy: ScrollStrategy.Vertical, // or Horizontal
defaultPageGap: 10,
}),
]Usage
The <Scroller /> Component
The <Scroller /> component is the heart of the layout system. It must be placed inside a <Viewport />.
You must provide the documentId to link the scroller to the correct document state. The snippet is called for each visible page, receiving layout information, allowing you to render the page content (e.g., using <RenderLayer />).
<script lang="ts">
import { Viewport } from '@embedpdf/plugin-viewport/svelte';
import { Scroller, type RenderPageProps } from '@embedpdf/plugin-scroll/svelte';
import { RenderLayer } from '@embedpdf/plugin-render/svelte';
let { documentId }: { documentId: string } = $props();
</script>
{#snippet renderPage(page: RenderPageProps)}
<div
style:width="{page.width}px"
style:height="{page.height}px"
style:position="relative"
>
<RenderLayer {documentId} pageIndex={page.pageIndex} />
</div>
{/snippet}
<Viewport {documentId}>
<Scroller {documentId} {renderPage} />
</Viewport>Page Navigation
To build navigation controls (like “Next Page” or “Go to Page 5”), use the useScroll store. This store requires a getter for the documentId of the target document.
<script lang="ts">
import { useScroll } from '@embedpdf/plugin-scroll/svelte';
let { documentId }: { documentId: string } = $props();
const scroll = useScroll(() => documentId);
</script>
{#if scroll.provides}
<div>
<span>Page {scroll.state.currentPage} of {scroll.state.totalPages}</span>
<button onclick={() => scroll.provides?.scrollToNextPage()}>Next</button>
</div>
{/if}Live Examples
Page Navigation
This example features a complete page navigation component that allows jumping to a specific page and moving forward or backward.
API Reference
Configuration (ScrollPluginConfig)
| Option | Type | Description |
|---|---|---|
defaultStrategy | ScrollStrategy | The default scroll direction (Vertical or Horizontal). Default: Vertical |
defaultPageGap | number | Pixel gap between pages. Default: 10 |
defaultBufferSize | number | Number of pages to render outside the visible viewport. Default: 2 |
Component: <Scroller />
The virtualized container that lays out pages.
| Prop | Type | Description |
|---|---|---|
documentId | string | (Required) The ID of the document to render. |
renderPage | Snippet<RenderPageProps> | (Required) A snippet that defines how to render each page. |
Snippet Props (RenderPageProps)
| Property | Type | Description |
|---|---|---|
pageIndex | number | The zero-based index of the page. |
width | number | The calculated width of the page in pixels. |
height | number | The calculated height of the page in pixels. |
scale | number | The current scale factor applied to the page. |
rotation | number | The rotation angle in degrees. |
Store: useScroll(documentId)
Returns the scroll state and capability methods for a specific document.
Parameters
| Parameter | Type | Description |
|---|---|---|
documentId | () => string | A getter function that returns the document ID to track. |
Returns
| Property | Type | Description |
|---|---|---|
state | { currentPage: number, totalPages: number } | Reactive state object containing the current page info. |
provides | ScrollScope | null | An object with methods to control scrolling and navigation. |
provides Methods (ScrollScope)
| Method | Description |
|---|---|
scrollToPage(options) | Scrolls to a specific page. options: { pageNumber, behavior?, center? }. |
scrollToNextPage() | Scrolls to the next page or spread. |
scrollToPreviousPage() | Scrolls to the previous page or spread. |
setScrollStrategy(s) | Changes the scroll strategy (e.g. to ScrollStrategy.Horizontal) for this document. |
Events (ScrollCapability)
Access events via useScrollCapability().
| Event | Payload | Description |
|---|---|---|
onLayoutReady | { documentId, isInitial } | Fires when a document’s layout is ready for interaction. isInitial is true only on the first layout after document load, false on subsequent layouts (e.g., when switching tabs). |
onPageChange | { documentId, pageNumber, totalPages } | Fires when the current page changes. |
onScroll | { documentId, metrics } | Fires on scroll with detailed viewport metrics. |
Need Help?
Join our community for support, discussions, and to contribute to EmbedPDF's development.