BlazorSyncScrolling 1.0.0

dotnet add package BlazorSyncScrolling --version 1.0.0
                    
NuGet\Install-Package BlazorSyncScrolling -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BlazorSyncScrolling" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BlazorSyncScrolling" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="BlazorSyncScrolling" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add BlazorSyncScrolling --version 1.0.0
                    
#r "nuget: BlazorSyncScrolling, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package BlazorSyncScrolling@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=BlazorSyncScrolling&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=BlazorSyncScrolling&version=1.0.0
                    
Install as a Cake Tool

BlazorSyncScrolling

A Blazor component library that enables synchronized scrolling between multiple PDF viewers and scrollable containers. Perfect for comparing documents, reviewing changes, or presenting multiple related documents simultaneously.

NuGet License: MIT .NET

Features

  • Synchronized Scrolling: Coordinate scrolling across multiple PDF viewers or any scrollable containers
  • PDF Viewing: Built-in PDF viewer component using PDF.js
  • Flexible Architecture: Easy-to-extend base classes for custom synchronized components
  • Real-time Coordination: Smooth, responsive scroll synchronization
  • Zoom Controls: Independent zoom controls for each PDF viewer
  • Page Tracking: Monitor and navigate through pages in PDF documents
  • Toggle Synchronization: Enable/disable sync on demand
  • Blazor WebAssembly & Server: Works with both hosting models

Demo

Check out the live demo to see the library in action.

Installation

Package Manager Console

Install-Package BlazorSyncScrolling

.NET CLI

dotnet add package BlazorSyncScrolling

PackageReference

<PackageReference Include="BlazorSyncScrolling" Version="1.0.0" />

Quick Start

1. Add to Program.cs

using BlazorSyncScrolling;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");

// Add BlazorSyncScrolling services
builder.Services.AddBlazorSyncScrolling();

await builder.Build().RunAsync();

2. Add PDF.js to your index.html

<!DOCTYPE html>
<html>
<head>
    

    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/5.0.375/pdf.min.mjs"></script>
    <script>
        pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/5.0.375/pdf.worker.mjs';
    </script>
</head>
<body>
    
</body>
</html>

3. Basic Usage

@page "/"
@using BlazorSyncScrolling
@using BlazorSyncScrolling.Components

<h1>Synchronized PDF Viewer</h1>

<SyncScrollCoordinator @bind-IsEnabled="@isSyncEnabled">
    <div class="row">
        <div class="col-md-6">
            <PdfViewer
                ScrollableContainerId="pdf1"
                CanSyncScroll="@isSyncEnabled"
                PdfData="@pdfData1"
                @bind-PageNumber="@currentPage1"
                @bind-ZoomLevel="@zoomLevel1" />
        </div>
        <div class="col-md-6">
            <PdfViewer
                ScrollableContainerId="pdf2"
                CanSyncScroll="@isSyncEnabled"
                PdfData="@pdfData2"
                @bind-PageNumber="@currentPage2"
                @bind-ZoomLevel="@zoomLevel2" />
        </div>
    </div>
</SyncScrollCoordinator>

<button @onclick="ToggleSync">
    @(isSyncEnabled ? "Disable" : "Enable") Sync
</button>

@code {
    private bool isSyncEnabled = true;
    private byte[] pdfData1;
    private byte[] pdfData2;
    private int currentPage1 = 1;
    private int currentPage2 = 1;
    private double zoomLevel1 = 1.0;
    private double zoomLevel2 = 1.0;

    private void ToggleSync()
    {
        isSyncEnabled = !isSyncEnabled;
    }
}

Components

SyncScrollCoordinator

The root component that manages synchronization state across all child components.

Parameters:

  • IsEnabled (bool): Controls whether synchronization is active
  • ChildContent (RenderFragment): Child components to coordinate

Example:

<SyncScrollCoordinator @bind-IsEnabled="@syncEnabled">
    
</SyncScrollCoordinator>

PdfViewer

A complete PDF viewer component with built-in synchronization support.

Parameters:

  • ScrollableContainerId (string): Unique identifier for the viewer
  • CanSyncScroll (bool): Whether this viewer participates in synchronization
  • PdfData (byte[]): PDF file data
  • PageNumber (int): Current page number (two-way binding)
  • ZoomLevel (double): Zoom level (two-way binding)
  • Height (string): Container height (default: "600px")

Example:

<PdfViewer
    ScrollableContainerId="document1"
    CanSyncScroll="true"
    PdfData="@pdfBytes"
    @bind-PageNumber="@currentPage"
    @bind-ZoomLevel="@zoom" />

Advanced Usage

Creating Custom Synchronized Components

You can create your own synchronized scrollable components by inheriting from SyncScrollable:

@inherits SyncScrollable

<div id="@ScrollableContainerId" class="custom-scrollable">
    @* Your scrollable content *@
</div>

@code {
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // Initialize your component
            await InitializeScrolling();
        }
        await base.OnAfterRenderAsync(firstRender);
    }
}

Handling File Uploads

<InputFile OnChange="@LoadFile" accept=".pdf" />

@code {
    private async Task LoadFile(InputFileChangeEventArgs e)
    {
        var file = e.File;
        if (file != null)
        {
            using var stream = file.OpenReadStream(maxFileSize: 50 * 1024 * 1024); // 50MB limit
            using var memoryStream = new MemoryStream();
            await stream.CopyToAsync(memoryStream);
            pdfData = memoryStream.ToArray();
        }
    }
}

Programmatic Scroll Control

@inject IJSRuntime JSRuntime

private async Task ScrollToPage(int pageNumber)
{
    await JSRuntime.InvokeVoidAsync("scrollToPage", ScrollableContainerId, pageNumber);
}

JavaScript Interop

The library provides JavaScript functions for advanced scenarios:

// Load a PDF programmatically
await window.loadPdf(containerId, pdfData, zoomLevel);

// Register custom scroll handlers
window.registerScrollHandler(containerId, (scrollData) => {
    console.log(`Scrolled to position: ${scrollData.scrollTop}`);
});

// Synchronize scroll positions manually
window.scrollSynchronizer.syncScroll(sourceId, targetIds, scrollData);

Browser Support

  • Chrome 90+
  • Firefox 88+
  • Safari 14+
  • Edge 90+

Dependencies

  • .NET 9.0
  • PDF.js 5.0+
  • Bootstrap 5 (optional, for styling)

Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

  1. Clone the repository
git clone https://github.com/yourusername/BlazorSyncScrolling.git
  1. Build the solution
dotnet build
  1. Run the sample app
dotnet run --project BlazorSyncScrolling.SampleApp

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Acknowledgments

  • PDF.js - Mozilla's JavaScript PDF viewer
  • Blazor - Microsoft's web UI framework
Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 196 9/29/2025