UNPKG

react-pdf-cropper

Version:

A fast, modular React library for cropping, watermarking and downloading regions of PDFs.

206 lines (137 loc) 7.56 kB
# react-pdf-cropper > A blazing fast, customizable PDF cropper for React. > Drag, resize, crop, watermark, preview, and download any region of any PDF—right from your web app. ## ✨ Features - 🖼 **Drag, resize, and move** the selection box with mouse or touch—just like an image editor. - 💡 **Works with any PDF renderer**: drop into [react-pdf-viewer](https://react-pdf-viewer.dev/), your own PDF.js setup, or any HTML canvas-based viewer. -**Zero dependency screenshot**: Crops directly from PDF.js canvas, no html2canvas needed, no lag. - 🪄 **Add your logo or watermark** to any cropped image. - 💾 **Instant download utility**: Save your crop with one click. - 🧩 **Fully UI-agnostic**: Hide built-in buttons, add your own controls anywhere. - 🤲 **Hooks & external control**: All actions (crop, cancel, download) available outside the cropbox. - 🚀 **Production-ready**: Used in real-world news, content, and SaaS workflows. ## 📦 Installation ``` npm install react-pdf-cropper # or yarn add react-pdf-cropper ``` ## 🚀 Quick Example With [react-pdf-viewer](https://react-pdf-viewer.dev/) ``` import React, { useRef, useState, useCallback } from "react"; import { Worker, Viewer } from "@react-pdf-viewer/core"; import { defaultLayoutPlugin } from "@react-pdf-viewer/default-layout"; import PDFCropperOverlay, { handleDownload, CropPreviewButton, CancelCropButton } from "react-pdf-cropper"; import "@react-pdf-viewer/core/lib/styles/index.css"; import "@react-pdf-viewer/default-layout/lib/styles/index.css"; function App() { const containerRef = useRef(); const [pdfFile, setPdfFile] = useState("/sample.pdf"); const [croppedImage, setCroppedImage] = useState(null); const [page, setPage] = useState(1); const [isCropping, setIsCropping] = useState(false); const [handlers, setHandlers] = useState({}); // Cropper overlay gives you crop/cancel handlers for your own buttons const getHandlers = useCallback((handlers) => setHandlers(handlers), []); return ( <div> <button onClick={() => setIsCropping(true)} disabled={isCropping}> Start Cropping </button> {isCropping && ( <> <CancelCropButton onClick={handlers.stopCropping} /> <CropPreviewButton onClick={handlers.handleSaveClick} /> </> )} <div ref={containerRef} style={{ position: "relative", width: 800, height: 900 }}> <Worker workerUrl="https://unpkg.com/pdfjs-dist@3.11.174/build/pdf.worker.min.js"> <Viewer fileUrl={pdfFile} plugins={[defaultLayoutPlugin()]} onPageChange={e => setPage(e.currentPage + 1)} /> </Worker> <PDFCropperOverlay containerRef={containerRef} isCropping={isCropping} setIsCropping={setIsCropping} currentPage={page} onCrop={setCroppedImage} getHandlers={getHandlers} showDefaultButtons={false} // Use your own buttons! /> </div> {croppedImage && ( <> <img src={croppedImage} alt="Cropped" style={{ maxWidth: 400, border: "1px solid #ddd" }} /> <button onClick={() => handleDownload(croppedImage)}> Download Cropped Image </button> </> )} </div> ); } export default App; ``` ## 🧩 API Reference ### `<PDFCropperOverlay />` | Props | Type | Required | Description | | -------------------- | -------- | -------- | -------------------------------------------------------------------------------------- | | `containerRef` | `ref` | ✔ | Ref to the DOM element containing your PDF page canvas | | `isCropping` | `bool` | ✔ | Should the cropping overlay be active? (controlled from your app) | | `setIsCropping` | `func` | ✔ | Function to close/hide cropping overlay (used by cancel, after crop, etc.) | | `currentPage` | `number` | ✔ | The current page number (1-based, not zero-indexed) | | `onCrop` | `func` | | Callback called with the cropped image `dataURL ((dataUrl) => {})` | | `getHandlers` | `func` | | Callback giving you crop/cancel handlers (`({ handleSaveClick, stopCropping }) => {}`) | | `watermarkImage` | `string` | | (Optional) URL/data URL for watermark logo/image | | `watermarkProps` | `object` | | (Optional) `{ opacity, tileWidth, tileHeight }` for watermark tiling | | `showDefaultButtons` | `bool` | | Show built-in crop/cancel buttons in cropbox? (default: `true`) | --- ### Exported Buttons - `<CropPreviewButton onClick={...} />` — Use in your own UI to trigger crop/preview. - `<CancelCropButton onClick={...} />` — Use in your own UI to cancel cropping. ### Utility - `handleDownload(imageDataUrl, filename = "cropped-image.png")` — Instantly download the cropped image. ## 🎨 Customization - **External UI**: Pass `showDefaultButtons={false}` to hide the cropbox’s own buttons and use the exported buttons in your layout. - Watermark: Add `watermarkImage="/logo.png"` and tweak `watermarkProps` as needed. - Styling: Tweak cropbox and buttons in your own CSS or fork to change cropbox design. ## 📁 Example Project A full-featured example React app is included in the [example/](https://github.com/shivam27k/react-pdf-cropper) folder of this repo. - Open it, run `npm install`, then `npm run dev`. - Try cropping, previewing, downloading, and watermarking on any PDF (don't forget to install the package first). There is an example video in the `public` folder for your reference as well. ## 💡 FAQ Q: Does this support touch/mobile? A: Yes! All drag, resize, and crop actions are available via mouse and touch. Q: Do I need to use `react-pdf-viewer`? A: No! Any PDF viewer that renders to a canvas (from PDF.js) will work, as long as you pass a ref to the container with the canvas. Q: Is html2canvas used? A: No. Cropping works directly on the PDF.js-rendered canvas, so it’s much faster and sharper. Q: Can I style the crop box? A: Yes—either with your own CSS, or by modifying the CroppingBox component. Q: Can I use my own crop/cancel buttons? A: Yes! Just hide the built-in ones and use the exported `<CropPreviewButton />` and `<CancelCropButton />`, passing the handlers from `getHandlers`. Q: How do I add a watermark? A: Pass a watermark image and optionally watermarkProps (opacity, tiling, etc). ## 🛠️ Contributing PRs and issues are very welcome! 1. Fork this repo 2. Add features or fixes in a branch 3. Add/adjust an example in example/ if needed 4. PRs should be clear and well-commented. ## 👤 Author Made by Shivam Kumar >\_< [GitHub](https://github.com/shivam27k) | [LikedIn](https://linkedin.com/shivam-27k) ## 📑 License > MIT — Free for personal, commercial, and open-source use. --- Questions? Open an issue or ping me on GitHub. Enjoy cropping PDFs with React! 🎉