[pdf.js] テキスト選択出来るスライド表示ライブラリを書いた
pdf.js-controllerというライブラリを書きました。
名前の通りmozilla/pdf.jsを扱うものです。 PDFをスライドのようなページめくりをするものを作るときに簡単に作れるようにする目的で作成しています。
実際に以下のスライドはこのライブラリを使って動作しています。
使い方
npm install pdf.js-controller
インストールして、以下のように書くだけでとりあえずpdfを表示できます。 普通にpdf.jsを扱うと文字列の選択ができない、日本語が文字化けする、リンクがクリック出来ないなどハマりどころがたくさんあります。
このライブラリではpdfjs-distのディレクトリをpdfDistDir
で指定する以外はあまり意識しなくても自動的にやってくれます。
(pdfjs-distはdependenciesとして入ってるので自動的に入ります)
// container element
var container = document.getElementById("pdf-container");
var PDFController = require("pdf.js-controller");
var controller = new PDFController({
container: container,
// path to dir of pdfjs-dist
pdfDistDir: __dirname + "/node_modules/pdfjs-dist/"
});
// path to URL of pdf.
// Apply CORS to this path. It means that the URL should be same origin.
var PDFURL = "./example.pdf";
controller.loadDocument(PDFURL)
.then(initializedEvent)
.catch(function (error) {
console.error(error);
});
container.addEventListener(PDFController.Events.before_pdf_rendering, function (event) {
// before render
});
container.addEventListener(PDFController.Events.after_pdf_rendering, function (event) {
// after render
});
function initializedEvent() {
window.addEventListener("resize", function (event) {
controller.fitItSize();
});
document.onkeydown = function (event) {
var kc = event.keyCode;
if (event.shiftKey || event.ctrlKey || event.metaKey) {
return;
}
if (kc === 37 || kc === 40 || kc === 75 || kc === 65) {
// left, down, K, A
event.preventDefault();
controller.prevPage();
} else if (kc === 38 || kc === 39 || kc === 74 || kc === 83) {
// up, right, J, S
event.preventDefault();
controller.nextPage();
}
};
}
pdfjs-distには言語別の情報が入ったcmaps
というデータやWebWorkerのスクリプトが含まれています。
そのため、ウェブに上げるときはpdfDistDirのディレクトリも参照出来る場所に必要です。
仕組み
以下の画像をみてもらうと分かりますが、pdf.jsはCanvasとテキスト、アノテーションの3つのレイヤーを使って描画しています。
Canvasにはそもそも文字列選択機能が存在しないため、このような作りになっています。 つまりCanvasの描画の上に透明なdivにテキストを流しこんだり、クリック出来るようにリンクを置いたりしています。
Firefoxの3D Viewで見てみるとそれぞれがレイヤーになっていることが分かりやすいです。
全体像3D
CanvasはPDFの内容を描画しています。
テキストレイヤーにはテキストが流し込まれています。
アノテーションコンテナにはリンクなどのPDFにおけるアノテーション情報が入っています。
デフォルトではCanvasのレイヤーしかないため、テキストやアノテーションは自分で行う必要があります。 そこを作るのが複雑なので、今回はその辺を隠蔽したpdf.js-controllerを作りました。
元々、azu/slide-pdf.jsで実装してありましたが、ライブラリとして切り離した感じです。
FirefoxのビルトインのpdfビューアライクのUIを利用したいだけの場合は、pdf.js/viewer.html at master · mozilla/pdf.jsあたりを見るといいです。(iframeで表示するとかできます)
おわりに
スライド共有サービス sharedoc を作りました - onk.ninjaを見ていて、未だにpdf.jsの扱いがとっても面倒そうだったのでライブラリとして切り出しました。
pdf.jsは意外と動いて面白いのと、技術的なスライドサービスでリンクがクリック出来ないのは辛いので何か頑張って欲しいと思いました。
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。