Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Responsive PDF with Annotations layer #575

Closed
3 tasks done
douglasrcjames opened this issue May 18, 2020 · 6 comments
Closed
3 tasks done

Responsive PDF with Annotations layer #575

douglasrcjames opened this issue May 18, 2020 · 6 comments

Comments

@douglasrcjames
Copy link

  • I have read documentation in README
  • I have checked sample and test suites to see real life basic implementation
  • I have checked if this question is not already asked

What am I trying to achieve?

I want the PDF Document to scale down as the screen size scales down so everything looks good on mobile, while still maintaining the annotations layer for clickable links.

Describe solutions I've tried

I have pretty much the same problem as this unresolved issue: #339 , I tried his solution and a few others, to no avail. I can get the document page to scale down, but the annotations layer is not scaling down with the page.

I don't see anything that works with my setup, am I missing something to get the annotations layer to also be responsive?

My current code:
pdf.css:

.react-pdf__Document {
   display: flex !important;
   justify-content: center !important;
}

.react-pdf__Page__canvas, .react-pdf__Page__annotations {
   max-width: 100% !important;
   height: auto !important;
}

.pdf-container {
   background-color: lightgray;
   padding: 1% 0 10px 0;
}

@media screen and (min-width: 901px) and (max-width: 1600px) {
   .pdf-container {
      padding: 5% 0 10px 0;
   }
  }

  @media screen and (min-width: 701px) and (max-width: 900px) {
   .pdf-container {
      padding: 10% 0 10px 0;
   }
  }

  @media screen and (max-width: 700px) {
   .pdf-container {
      padding: 20% 0 10px 0;
   }
  }

Article component:

 <React.Fragment>
    <div className="pdf-container">
        <Document
            file={this.props.article.pdfUrl}
            onLoadSuccess={this.onDocumentLoadSuccess}
        >
            <Page pageNumber={pageNumber} />
        </Document>
        <Grid fluid className="s-padding-t">
            <Row center="xs">
                <Col xs={12} sm={4} className="s-padding-b">
                    <button
                        type="button"
                        className="s-btn"
                        disabled={pageNumber <= 1}
                        onClick={this.previousPage}
                        >
                        <i className="fa fa-chevron-left"></i> Previous
                    </button>
                </Col>
                <Col xs={12} sm={4} className="s-padding-b">
                    <span>Page {pageNumber || (numPages ? 1 : '--')} of {numPages || '--'}</span>
                </Col>
                <Col xs={12} sm={4} className="s-padding-b">
                    <button
                        type="button"
                        className="s-btn"
                        disabled={pageNumber >= numPages}
                        onClick={this.nextPage}
                        >
                        Next <i className="fa fa-chevron-right"></i>
                    </button>
                </Col>
            </Row>
        </Grid>
    </div>
</React.Fragment>

Environment

  • Browser (if applicable) [e.g. Chrome 57, Firefox 59]: Chrome 57
  • React-PDF version: ^4.1.0
  • React version: ^16.13.1
@oldboyxx
Copy link

Don't fiddle with css, just set page width like this:

<div ref={documentWrapperRef}>
  <Document file="some_url">
    <Page
      width={documentWrapperRef.current?.getBoundingClientRect().width || undefined}
    />
  </Document>
</div>

@wojtekmaj
Copy link
Owner

@oldboyxx Would be good to use e.g. ResizeObserver on documentWrapperRef, but your solution is definitely getting there :) React-PDF gotta know the exact render size to render all layers properly.

@rootlinux2
Copy link

When I use this fix, I have a new issue, each time I change the page the content around blink or move!!! Any idea?

@gugol2
Copy link

gugol2 commented Oct 29, 2020

How do you add zoomIn/zoomOut capabilities when having a fixed width?

@Dev-Dipesh
Copy link

Dev-Dipesh commented Jan 12, 2021

@gugol2 This code below worked perfectly for the following conditions:

  1. Fixed width
  2. Zoom In/Out
  3. Fullscreen
  4. Focus mode: it toggles the sidebar visibility for distraction-free reading

Note: I have multiplied with 0.95 to give some space to my pdf control toolbar in my UI.

Default state

const [isFullscreen, setIsFS] = useState(false);
const [scale, setScale] = useState(0.6);
const [sidebar, setSidebar] = useState(true);

const pdfWrapperRef = React.useRef();

Toolbar Zoom In/Out & Focus Mode

<Tooltip placement="left" title="Zoom Out">
  <ToolbarButton
    type="primary"
    icon={<MinusOutlined />}
    disabled={scale <= 0.4}
    onClick={() => setScale(scale-0.2)}
  />
</Tooltip>
<Tooltip placement="left" title="Zoom In">
  <ToolbarButton
    type="primary"
    icon={<PlusOutlined />}
    disabled={scale >= 1}
    onClick={() => setScale(scale+0.2)}
  />
</Tooltip>
<Tooltip
  placement="left"
  title={
    sidebar ? 'Activate Focus Mode' : 'De-activate Focus Mode'
  }
>
  <ToolbarButton
    type="primary"
    icon={<AimOutlined />}
    style={{
      background: sidebar ? '#fff' : '#0190be',
      color: sidebar ? '#0190be' : '#fff',
    }}
    onClick={() => {
      if(!sidebar) {
        setScale(0.8);
      }
      toggleSidebar(!sidebar);
    }}
  />
</Tooltip>

Passing props to PDF FC

<div ref={pdfWrapperRef}>
  <PDF
    pdf={pdf}
    scale={scale}
    page={pageNumber}
    pdfWrapperRef={pdfWrapperRef}
    onSuccess={onDocumentLoadSuccess}
  />
</div>

PDF Component
FirstPage component is the styled component of Page from react-pdf

const PDF: React.FC<PDFType> = ({
  pdf,
  scale,
  page,
  pdfWrapperRef,
  onSuccess,
}) => (
  <Document
    file={pdf}
    renderMode="canvas"
    loading={<LottieSplash animationData={splash} />}
    onLoadSuccess={onSuccess}
    onLoadError={console.error}
    error={
      'Unable to load the library article. Please reach out to the support for further assistance.'
    }
  >
    <Flex
      flexDirection="row"
      style={{
        justifyContent: 'space-around'
      }}
    >
      <FirstPage
        scale={scale}
        width={(
          pdfWrapperRef.current?.getBoundingClientRect().width*.95
        ) || undefined}
        pageNumber={page}
      />
    </Flex>
  </Document>
);

CleanShot 2021-01-12 at 15 03 47@2x

@SavageWilliam
Copy link

SavageWilliam commented May 26, 2021

@Dev-Dipesh

How did you handle fullscreen? Can't see it in your example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants