Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- react
- slice/splice/split
- redux상태유지
- 자바스크립트
- ㄷㅌ
- removeCookie
- 내장고차함수
- CSS
- 자바스크립트#JS#slice#splice
- js
- toString#String
- UI
- 노드교과서
- 자바스크립트#JS#var#let#const#undefined#null
- for~in/for~of
- https://dasima.xyz/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%A0%9C%EA%B3%B1-math-pow-%EA%B3%84%EC%82%B0/
- variable#function
- https://lo-victoria.com/introduction-to-redux-toolkit-for-beginners
- https://developer-talk.tistory.com/299
- Beesbeesbees
- 자바스크립트#조건문#문자열
- dom
- UX
- 헷갈린다~
- children vs childrenNodes
- https://www.daleseo.com/js-array-slice-splice/
- JS#3일차달리자#초반인데#시간금방~
- @redux-toolkit
- User Flow
- cmarket
Archives
- Today
- Total
Daily Front_Minhhk
[next.js] react-pdf__적용 (+ zoom in/out) 본문
pdf 뷰어 다시 적용할 작업이 생겨!
오랜만에 리마인드 느낌으로 다시 작성@
next.config.mjs 파일 수정!!
const nextConfig = {
//? react-pdf__config 설정____________________
webpack: config => {
config.resolve.alias.canvas = false;
return config;
},
};
뷰어 전체 컴포넌트와 pdf컴포넌트 따로 작성한다.
pdf 파일 데이터를 받아 base64Decoding 한다.
변환 코드는 util 에 넣어 사용!
export const base64Decoding = (base64String: string) => {
if (!base64String) return "";
const decodedData = atob(base64String);
const byteArray = new Uint8Array(decodedData.length);
for (let i = 0; i < decodedData.length; i++) {
byteArray[i] = decodedData.charCodeAt(i);
}
const blob = new Blob([byteArray], { type: "application/pdf" });
return URL.createObjectURL(blob);
};
Zoon In / Out
- scale state 를 만들어서,, pdfViewer 의 scale 옵션값에 넣어 줄 것이다.
- 아래는 관련 함수들
const [scale, setScale] = useState<number>(1);
// 최소는 0.2 , 최대는 2.4 까지
const handlePdfZoomOut = () => {
setScale(prevScale => Math.max(prevScale - 0.2, 0.2));
};
const handlePdfZoomIn = () => {
setScale(prevScale => Math.min(prevScale + 0.2, 2.4));
};
이제 연결할 Viewer 를 등록해보자 __ max-width 와 max-height 를 주고 overflow 를 줘야 나중에 확대/축소 했을 때 scroll 생기며 안 깨질 것이다.
그리고 pdfFile 과, scale 을 넘겨주자
<section className="w-full max-h-[635px] max-w-[1470px] overflow-x-auto overflow-y-auto">
<PdfViewer filePath={pdfFile} scale={scale} />
</section>
ContentsViewerComponent.tsx
export default function ContentsViewerComponent({ className }: { className: string }) {
...
const { data, isLoading } = usePdfGetQuery(path); //! query Get
const [pdfFile, setPdfFile] = useState<string>("");
useEffect(() => {
if (!isLoading && data && data.fileContent) {
const fileURL = base64Decoding(data.fileContent);
setPdfFile(fileURL);
}
}, [data, isLoading]);
//! PDF Zoom_____________________________________________________________________
const [scale, setScale] = useState<number>(1);
// 최소는 0.2 , 최대는 2.4 까지
const handlePdfZoomOut = () => {
setScale(prevScale => Math.max(prevScale - 0.2, 0.2));
};
const handlePdfZoomIn = () => {
setScale(prevScale => Math.min(prevScale + 0.2, 2.4));
};
return (
<div className={`${className} flex flex-col`}>
<section className="flex justify-between items-center text-16 font-600 border-b-[1px] border-gray-300 pb-2 px-2">
...
<div className="flex items-center">
<div className="w-16" />
<div className="flex items-center">
<TbFileSearch className="text-bgBlue text-22 mr-1" />
<p className="text-20 text-bgBlue font-600 mr-3">Pdf Zoom</p>
<FaMinusSquare
onClick={handlePdfZoomOut}
className="text-bgBlue text-30 hover:text-hoverColor transition cursor-pointer"
/>
<div className="text-20 text-bgBlue font-600 ml-3 mr-2">
{`${(scale * 100).toFixed(0)}%`}
</div>
<FaPlusSquare
onClick={handlePdfZoomIn}
className="text-bgBlue text-30 hover:text-hoverColor transition cursor-pointer"
/>
</div>
</div>
</section>
{/* pdf.js_viewer */}
<section className="w-full max-h-[635px] max-w-[1470px] overflow-x-auto overflow-y-auto">
<PdfViewer filePath={pdfFile} scale={scale} />
</section>
</div>
);
}
이제 본격적 PdfViewer 로 넘어가보자!
CDN 등록 해주고
import { Document, Page, pdfjs } from "react-pdf";
import "react-pdf/dist/Page/TextLayer.css";
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
스크롤로 pdf 를 보여줄 것이기 때문에, 파일이 로드가 완료 되면 pdf 파일의 페이지 숫자 만큼
배열로 만들어서 랜더링 할 거다.
function onDocumentLoadSuccess({ numPages }: { numPages: number }) {
setNumPages(numPages);
}
로딩이나 에러는 전체 스피너 처리 했다.
UX 적으로 보기 안좋았다. 로딩에 에러도 뜨고,,
pdfViewer 코드_
<div onContextMenu={e => e.preventDefault()}> // 우클릭 방지
<Document
file={filePath} // 받은 pdf filePath
onLoadSuccess={onDocumentLoadSuccess}
loading={PdfLoading}
error={PdfLoading}>
{/* scroll pdf */}
{Array.from(new Array(numPages), (_, i) => (
<Page
width={1200}
key={i}
pageNumber={i + 1}
loading={PdfLoading}
error={PdfLoading}
renderAnnotationLayer={false} // 양식 렌더링 false_ pdf 페이지 간격마다 빈공간 삭제
scale={scale} // 받은 scale 적용
/>
))}
</Document>
</div>
각각의 세부 옵션은 문서의
User guide
부분을 참조하자!
PdfViewer.tsx
"use client";
import React, { useState } from "react";
import Spinner from "@/components/common/spinner/Spinner";
//! import ㄱㄱ
import { Document, Page, pdfjs } from "react-pdf";
import "react-pdf/dist/Page/TextLayer.css";
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
function PdfViewer({
filePath,
scale,
}: {
filePath: string;
scale: number;
}) {
const [numPages, setNumPages] = useState<number>(0);
//! fn _____________________________________________________________________________
function onDocumentLoadSuccess({ numPages }: { numPages: number }) {
setNumPages(numPages);
}
const PdfLoading = () => {
return <Spinner />;
};
return (
// 우클릭 방지
<>
<div onContextMenu={e => e.preventDefault()}>
<Document
file={filePath}
onLoadSuccess={onDocumentLoadSuccess}
loading={PdfLoading}
error={PdfLoading}>
{/* scroll pdf */}
{Array.from(new Array(numPages), (_, i) => (
<Page
width={1200}
key={i}
pageNumber={i + 1}
loading={PdfLoading}
error={PdfLoading}
renderAnnotationLayer={false} // 양식 렌더링 false_ pdf 페이지 간격마다 빈공간 삭제
scale={scale}
/>
))}
</Document>
</div>
</>
);
}
export default React.memo(DesignInfoPdfViewer);
결과화면
'Code개발일지' 카테고리의 다른 글
[React] 파일 다운로드 훅_blob filedown hook (1) | 2024.12.08 |
---|---|
[vercel] react-vite vercel 간단 배포 (0) | 2024.12.08 |
[TanStack Query] isFetching vs isLoading (0) | 2024.02.25 |
React_클린 코드 간단 정리 (0) | 2024.01.21 |
[React, Next.js] 툴팁, 모달 등 외부 클릭 시 사라지게! (1) | 2024.01.11 |