Issues with promises when trying to load PDF as images on a canvas

57 views Asked by At

I'm trying to draw on a PDF, for that I'll use Konva to draw but I need to load the PDF as an image on the canvas.

import React, { useState, useRef, useEffect } from "react";
import { Stage, Layer, Image, Rect } from "react-konva";
import pdfjsWorker from "react-pdf/node_modules/pdfjs-dist/build/pdf.worker.entry";
import { pdfjs } from "react-pdf";


pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;


const CustomPdfReader = ({ url, width, template }) => {
    const [pages, setPages] = useState([]);
    const [rectangles, setRectangles] = useState([]);
  
    useEffect(() => {
      pdfjs.getDocument(url).promise
        .then((doc) => {
          const numPages = doc.numPages;
          const promises = [];
          for (let i = 1; i <= numPages; i++) {
            promises.push(
              doc.getPage(i)
                .then((page) => {
                  const canvas = document.createElement("canvas");
                  const context = canvas.getContext("2d");
                  const scale = width / page.getViewport({ scale: 1 }).width;
                  const viewport = page.getViewport({ scale });
                  canvas.width = viewport.width;
                  canvas.height = viewport.height;
                  return page.render({ canvasContext: context, viewport }).promise;
                })
                .catch((error) => {
                  console.error("Error in getting or rendering a page:", error);
                })
            );
          }
          Promise.all(promises)
            .then((canvases) => {
              setPages(canvases.map((canvas) => canvas.toDataURL()));
            })
            .catch((error) => {
              console.log(promises);
              console.error("Error in resolving all promises:", error);
            })
            .finally(() => {
              console.log("All promises are settled");
            });
        })
        .catch((error) => {
          console.error("Error in loading the PDF document:", error);
        });
    }, [url, width]);
  
    // handle mouse events to draw rectangles on the stage
    const stageRef = useRef();
    const handleMouseDown = (e) => {
      // get the mouse position relative to the stage
      const stage = e.target.getStage();
      const point = stage.getPointerPosition();
      // create a new rectangle with initial position and size
      const newRect = {
        x: point.x,
        y: point.y,
        width: 0,
        height: 0,
        fill: "green",
        opacity: 0.4,
      };
      // add the new rectangle to the rectangles state
      setRectangles([...rectangles, newRect]);
    };
  
    const handleMouseMove = (e) => {
      // get the mouse position relative to the stage
      const stage = e.target.getStage();
      const point = stage.getPointerPosition();
      // update the last rectangle in the rectangles state with the new size
      setRectangles((rectangles) => {
        const lastRect = rectangles[rectangles.length - 1];
        if (lastRect) {
          return [
            ...rectangles.slice(0, -1),
            {
              ...lastRect,
              width: point.x - lastRect.x,
              height: point.y - lastRect.y,
            },
          ];
        } else {
          return rectangles;
        }
      });
    };
  
    const handleMouseUp = (e) => {
      console.log(template);
      console.log(rectangles);
    };
  
    return (
      <div>
        <Stage
          ref={stageRef}
          width={width}
          height={window.innerHeight}
          onMouseDown={handleMouseDown}
          onMouseMove={handleMouseMove}
          onMouseUp={handleMouseUp}
        >
          <Layer>
            {pages.map((page, i) => (
              <Image key={i} image={page} />
            ))}
            {rectangles.map((rect, i) => (
              <Rect key={i} {...rect} />
            ))}
          </Layer>
        </Stage>
      </div>
    );
  };
  
  export default CustomPdfReader;

My issue is that react-pdf (or pdfjs) struggles with rendering the pages of a PDF in order, I tried using a promise to sorts that out but my promises are "[[PromiseResult]]:undefined" and I got an error "bundle.js:311 Error in resolving all promises: TypeError: Cannot read properties of undefined (reading 'toDataURL')" I'm struggling with this one

0

There are 0 answers