Как я создал PDF Ink для комфортного онлайн-обучения по книгам в формате PDF

Зачем читать PDF, если на них нельзя писать?

Всем привет! Я Альберт, и я люблю делать инструменты более удобными для работы.

Если вы когда-либо пробовали заниматься самообразованием, изучать учебники по программированию или читать сложные технические документы из PDF на своем ноутбуке или планшете, вы знакомы с этой проблемой. Вы открываете книгу, хотите выделить ключевой фрагмент кода, нарисовать стрелку-схему рядом с объяснением или оставить заметку на полях — и понимаете, что стандартные просмотрщики PDF либо перегружены функциями, либо платные, либо полностью теряют ваши рисунки при случайном обновлении вкладки.

Я хотел исправить это и создать PDF Ink — легкое и быстрое веб-приложение для чтения и интерактивного аннотирования PDF-книг прямо в браузере.


Идея и технологический стек

Главная цель состояла в том, чтобы построить инструмент, который:

  1. Запускается в один клик в любом современном браузере.
  2. Позволяет загружать любой локальный PDF-учебник.
  3. Позволяет рисовать на страницах с помощью мыши, стилуса или касания, а также вводить текстовые заметки.
  4. Самое главное: надежно сохраняет текущую страницу, уровень масштабирования, список библиотек и все заметки с рисунками локально, чтобы вы могли продолжить обучение в любой момент.

Для реализации я выбрал современный стек: React + TypeScript + Vite + TailwindCSS.
Для рендеринга PDF интегрировал надежную библиотеку pdfjs-dist (PDF.js) от Mozilla.


Двухслойная архитектура Canvas

Чтобы приложение оставалось быстрым во время рисования, я разделил рабочую область на два независимых слоя:

  1. Слой PDF: Статический фоновый <canvas>, который рендерит изображение страницы PDF с учетом масштаба.
  2. Слой аннотаций: Прозрачный верхний <canvas>, который перехватывает события указателя, рисует векторные штрихи и накладывает текст.

Благодаря этому рисование происходит мгновенно: когда вы рисуете линию, приложение обновляет только легкий слой векторных штрихов, не затрагивая тяжелый холст PDF.


Эволюция базы данных: Переход на IndexedDB v2

Первая версия сохраняла PDF-файл и все рисунки как один объект в IndexedDB. С большими книгами запись файла размером 20 МБ каждые 250 мс вызывала лаги интерфейса.

Я переписал менеджер IndexedDB для разделения файлов и аннотаций:

  1. Хранилище pdfs: Хранит исходный бинарный файл (ArrayBuffer) и записывается только один раз при импорте.
  2. Хранилище pdfs_metadata: Хранит легкие метаданные рисунков, страниц и текстов в JSON.

Теперь при рисовании обновляется только легкий объект метаданных. Запись занимает доли миллисекунды, полностью устраняя лаги!


Попробуйте сами!

Вы можете протестировать живую версию приложения здесь:
👉 Practice Book PDF APP Live App

Учитесь с удовольствием и пишите код, который делает жизнь проще!