何枚かつづりになっているPDFの中身をスライドショーにする

何枚か合体しているPDFファイルをスライドショーで表示させるデモです。
PDFをcanvasに表示させるためにPDF.jsを、スライドショーはSwiperを使用しています。

PDFをcanvasに書き出す

PDF.jsをimportして使おうとするとTypeScriptではエラーが出てしまう

下記の記事で解消できるかと思ったのですが、結局エラーは消えず、PDF.jsはHTMLに直接読ませることにしました。

  <!-- importするとエラーが出るのでPDF.jsを直接読ませる -->
  <script src="//mozilla.github.io/pdf.js/build/pdf.js"></script>

TypeScriptでPDF.jsを使う際「The browser/environment lacks native support for critical functionality used by the PDF.js library (e.g. `ReadableStream`); please use a `legacy`-build instead.’」が出た場合の対処法 – Qiita
https://qiita.com/shuichiro/items/828d9068b6acd17eb1eb

canvasをcreateElementする

PDFの枚数分Canvasが必要なので、forで関数renderを繰り返し処理していきます。
スライドショーにSwiperを使うので、canvasだけ出力するのではなく、swiper-slideクラスのついたdivで囲って出力していきます。

    // PDFの読み込み
    const render = (
      selectorsId: {
        canvasContainer: string;
      },
      index: number
    ) => {
      if (!state.pdf) return;
      state.pdf
        .getPage(state.currentPage)
        .then((page: any) => {
          //canvasをセット
          let target = <HTMLDivElement>(
            document.getElementById(selectorsId.canvasContainer)
          );
          let newCanvas = <HTMLCanvasElement>document.createElement("canvas");
          newCanvas.dataset.slidecanvas = `slideCanvas-${index}`;

          //Swiperでスライドする予定なので、swiper-slideクラスのついたdivで囲う
          let newSlideWrapper = <HTMLDivElement>document.createElement("div");
          newSlideWrapper.classList.add("swiper-slide");

          newSlideWrapper.appendChild(newCanvas);
          target.appendChild(newSlideWrapper);

          let ctx = newCanvas.getContext("2d");

          // 倍率を指定
          let viewport = page.getViewport({ scale: state.zoom });
          newCanvas.width = viewport.width;
          newCanvas.height = viewport.height;

          // レンダリング
          page.render({
            canvasContext: ctx,
            viewport: viewport
          });
        });
    };

    pdfjsLib.getDocument(this.pdfUrl).promise.then((pdf: any) => {
      state.pdf = pdf;
      //PDFが何枚か綴りになっているので、1枚づつcanvasに描画する。
      //PDF.jsの.getPage()が1から始まりなので、indexも1始まりで合わせたかった
      for (let i = 1; i <= state.pdf._pdfInfo.numPages; i++) {
        state.currentPage = i;
        render(this.selectorsId, i);
      }
    });

PDFをcanvasに書き出せたら、その後Swiperを動かす

.then()で繋げて、スライドショーするのに必要な要素の出力が終わったらSwiperを動かすようにします。

    pdfjsLib
      .getDocument(this.pdfUrl)
      .promise.then((pdf: any) => {
        state.pdf = pdf;
        //PDFが何枚か綴りになっているので、1枚づつcanvasに描画する。
        //PDF.jsの.getPage()が1から始まりなので、indexも1始まりで合わせたかった
        for (let i = 1; i <= state.pdf._pdfInfo.numPages; i++) {
          state.currentPage = i;
          render(this.selectorsId, i);
        }
      })
      .then(() => {
        //domを準備できたらswiper
        const option = {
          pagination: {
            el: ".swiper-pagination"
          },
          navigation: {
            nextEl: ".swiper-button-next",
            prevEl: ".swiper-button-prev"
          }
        };
        new Swiper(".swiper", option);
      });

ShowPdf.tsはindex.tsで呼び出しています。

const mainShowPdf = new ShowPdf("./src/assets/images/demo.pdf", {
      canvasContainer: "canvas-container"
    });
    mainShowPdf.setUp();

使用ライブラリ

PDF.js
https://mozilla.github.io/pdf.js/

Swiper
https://swiperjs.com/

参考サイト

【Javascript】PDF.jsを使ってPDFのプレビュー画面を作成する方法 | わくいげんきのウェブログ
https://g-weblog.com/blog/4

TypeScriptでPDF.jsを使う際「The browser/environment lacks native support for critical functionality used by the PDF.js library (e.g. `ReadableStream`); please use a `legacy`-build instead.’」が出た場合の対処法 – Qiita
https://qiita.com/shuichiro/items/828d9068b6acd17eb1eb