Skip to main content
Skip table of contents

Single Document Scroll Renderer

The SingleDocumentScrollRenderer is a renderer with a scrolling view. It displays one Content Document at a time and the user is able to scroll through the contents.

Navigation

The SingleDocumentScrollRenderer can be navigated by using the navigation methods provided by the ReaderView, as well as ReaderView.scrollBy() and by scrolling manually. ReaderView.previous() and ReaderView.next() will navigate to the previous/next Content Document.

Reading Position

The Reading Position will be updated normally after a navigation to a Locator. It will also be updated every time the user scrolls inside the document.

The Reading Area

The Reading Area defines the part of the renderer's visible area that will be used for calculations related to Reading Positions. If a SyncMediaPlayer is attached to the ReaderView and managed ReaderView synchronization is enabled, the Reading Area also has an impact on how the renderer synchronizes its visible content with the SyncMediaPlayer.

After a navigation using ReaderView.goTo(), or after scrolling so that the old Reading Position is outside the visible range, the new Reading Position will match the top of the Reading Area.

When SyncMediaPlayer playback causes the Reading Position to change, the renderer will, if necessary, automatically scroll to keep the Reading Position inside the Reading Area.

Changing the size of the Reading Area can be done by using the ISingleDocumentScrollRendererOptions, either by passing them as a parameter when creating a new SingleDocumentScrollRenderer or by using the setOptions() method. For more details see the API documentation.

Synchronization with a SyncMediaPlayer

There are a few different strategies for using the SingleDocumentScrollRenderer with a SyncMediaPlayer.

The recommended strategy is to set SyncMediaPlayer.setManagedReaderViewSynchronization({enabled: true}) and let the Colibrio Reading System manage the synchronization. Using this method has a few recommended settings to keep the user experience as smooth as possible.

TS
syncMediaPlayer.setManagedReaderViewSynchronizationOptions({
    enabled: true,
    alwaysSeekToSegmentStart: true
})

syncMediaPlayer.setReaderViewSynchronizationWaitBehavior(SyncMediaReaderViewSynchronizationWaitBehavior.DONT_WAIT)

Setting the alwaysSeekToSegmentStart to true ensures that the SyncMediaPlayer will always start playing from the start of a segment, even after scrolling so that the Reading Position ends up in the middle of a segment. This, however, may cause the SyncMediaPlayer to attempt playing content that is before the visible content. Therefore it is also recommended to set the SyncMediaReaderViewSynchronizationWaitBehavior.DONT_WAIT.

Another strategy is to let the SyncMediaPlayer play independently of the ReaderView, using SyncMediaPlayer.setManagedReaderViewSynchronization({enabled: false}) and manually call SyncMediaPlayer.attemptReaderViewSynchronization() when the user presses a button to either navigate the renderer to the current SyncMediaTimelinePosition or seek the SyncMediaPlayer to the current Reading Position.

Scroll Events

A list of the scroll related events. Please refer to the API documentation for more details.
rendererScrollCanceled
rendererScrollEnded
rendererScrollHeightChanged
rendererScrollStarted

Common use cases

Check if the renderer is scrolled all the way down

The following code example shows you how you can detect if the renderer has scrolled to the bottom of a document.

TS
const mainView: IReaderView;
let isAtBottom = false;

/**
 * Function to see if the renderer has scrolled to the bottom of the current document.
 */
function checkIfScrolledToBottom(readerView: IReaderView): void {
    const scrollState = readerView.getScrollState();
    if (!scrollState) {
        return;
    }

    if (scrollState.rendererClientHeight + scrollState.scrollTop >= scrollState.scrollHeight) {
        isAtBottom = true;
    } else {
        isAtBottom = false;
    }
}

/*
 * You need to listen to both events to make sure that it will trigger even when there is a short
 * document so there is no scrolling happening.
 */
mainView.addEngineEventListener('rendererScrollEnded', evt => {
    checkIfScrolledToBottom(evt.readerView);
});
mainView.addEngineEventListener('rendererScrollHeightChanged', evt => {
    checkIfScrolledToBottom(evt.readerView);
});
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.