그누보드 스킨 mp4 및 PDF 첨부 보기 다중 PDF 보기 통합(PDFObject + PDF.js) — PC/모바일 자동 대응
동작 적용 상태
https://www.11q.kr/bbs/board.php?bo_table=cording&wr_id=28
여기에
적용한 스킨/보드
w:\g5\skin\board\BS4-Basic-Webzine_11q_mp4_pdf.zip
적용파일 참조 드립니다
다중 PDF 보기 통합(PDFObject + PDF.js) — PC/모바일 자동 대응
주요 기능
-
다중 PDF 지원
-
게시글에 여러 개 PDF 첨부파일이 있어도 각 파일마다 버튼과 뷰어 자동 생성
-
예:
sample1.pdf,sample2.pdf,sample3.pdf→ 각각 버튼으로 열기 가능
-
-
PC/모바일 자동 구분
-
PC → PDFObject 사용 (메뉴/확대/축소 기능 제공)
-
모바일 → PDF.js 사용 (화면 폭 기준 전체 페이지 스케일링)
-
-
버튼 토글
-
PDF 보기 버튼 클릭 → PDF 열기
-
다시 클릭 → PDF 닫기
-
각 PDF마다 독립적으로 열기/닫기 가능
-
-
모바일 화면 최적화
-
화면 폭 기준으로 페이지 전체가 보이도록 자동 축소
-
세로 스크롤로 전체 페이지 확인 가능
-
-
오류 처리
-
PDF 로딩 실패 시 오류 메시지 표시
-
설명
-
배경
-
그누보드 게시글에서 PDF 첨부파일을 PC와 모바일 모두에서 바로 볼 수 있도록 통합 구현
-
기존 PDFObject는 모바일에서 잘 동작하지 않는 문제 해결
-
-
작동 방식
-
$view['file']배열 반복 -
각 PDF 파일마다 버튼과 컨테이너 생성
-
PC/모바일 구분 후 적절한 라이브러리(PDFObject / PDF.js)로 PDF 렌더링
-
모바일은 PDF Base64 데이터를 읽어서
canvas로 페이지 렌더링 -
버튼 클릭 시 열기/닫기 토글
-
-
코드 구조
-
버튼 생성 영역
<button id="pdfToggleBtn_1">첨부된 PDF 바로보기 (파일명)</button> -
PDF 컨테이너 영역
<div id="pdfcontainer_1" style="width:100%; max-height:100vh; overflow-y:auto; display:none;"></div> -
PC/모바일 렌더링 스크립트
-
PDFObject:
PDFObject.embed(pdf_url, "#container_id") -
PDF.js: Base64 데이터를 읽어
canvas로 페이지 렌더링, 화면 폭 기준 스케일링
-
-
-
사용자 경험
-
PC에서는 기존 PDF 보기와 동일하게 메뉴와 축소/확대 기능 사용 가능
-
모바일에서는 화면 전체에 맞춰 PDF가 작게 표시되며 세로 스크롤로 전체 페이지 확인 가능
-
???? 정리
-
다중 PDF 지원 + PC/모바일 통합 + 버튼 토글 기능
-
모바일에서는 전체 페이지 축소/스케일링, PC에서는 PDFObject 그대로 유지
-
게시글에 PDF 첨부만 되어 있으면 별도 설정 없이 자동 동작
본 적용내용을
다음 소스를
w:\g5\skin\board\BS4-Basic-Webzine_11q\view.skin.php
에 글보기 마지막에 추가 사용합니다
<hr class="hr"/>
<!-- PDF 보기 2025_0923_2350_29 -->
<!-- PDF 버튼 클릭으로 보기동작및 PDF 보기 영역을 본문 내용 끝 에 추가 -->
<!-- PDF 보기 (다중 PDF, PC/모바일 통합, 실제 첨부 기반) -->
<?php
if (isset($view['file']) && is_array($view['file'])) {
$pdfIndex = 0; // 각 PDF마다 고유 ID 부여
foreach ($view['file'] as $file) {
$ext = strtolower(pathinfo($file['source'], PATHINFO_EXTENSION));
if ($ext === 'pdf') {
$pdfIndex++;
$pdf_url = G5_DATA_URL.'/file/'.$bo_table.'/'.$file['file'];
$pdf_path = G5_DATA_PATH.'/file/'.$bo_table.'/'.$file['file'];
$pdf_base64 = file_exists($pdf_path) ? base64_encode(file_get_contents($pdf_path)) : '';
$btnId = "pdfToggleBtn_$pdfIndex";
$containerId = "pdfcontainer_$pdfIndex";
?>
<div style="margin:20px 0">
<button id="<?php echo $btnId; ?>">첨부된 PDF 바로보기 (<?php echo $file['source']; ?>)</button>
</div>
<div id="<?php echo $containerId; ?>" style="width:100%; max-height:100vh; overflow-y:auto; border:1px solid #ccc; display:none;"></div>
<!-- PC용 PDFObject -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfobject/2.2.8/pdfobject.min.js"></script>
<!-- 모바일용 PDF.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js"></script>
<script>
(function() {
const btn = document.getElementById("<?php echo $btnId; ?>");
const container = document.getElementById("<?php echo $containerId; ?>");
let isPdfOpen = false;
btn.addEventListener("click", function () {
if (!isPdfOpen) {
container.innerHTML = "";
container.style.display = "block";
if (/Mobi|Android/i.test(navigator.userAgent)) {
// 모바일 → PDF.js Base64 렌더링
const pdfData = atob("<?php echo $pdf_base64; ?>");
pdfjsLib.getDocument({ data: pdfData, disableWorker: true }).promise.then(function(pdf) {
let pageNum = 1;
function renderPage() {
if (pageNum > pdf.numPages) return;
pdf.getPage(pageNum).then(function(page) {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const containerWidth = container.clientWidth;
const viewport = page.getViewport({ scale: 1 });
const scale = containerWidth / viewport.width;
const scaledViewport = page.getViewport({ scale: scale });
canvas.width = scaledViewport.width;
canvas.height = scaledViewport.height;
page.render({ canvasContext: ctx, viewport: scaledViewport }).promise.then(() => {
container.appendChild(canvas);
pageNum++;
renderPage();
});
});
}
renderPage();
}).catch(err => {
container.innerHTML = "PDF 로딩 실패: " + err.message;
});
} else {
// PC → PDFObject 사용
PDFObject.embed("<?php echo $pdf_url; ?>", "#<?php echo $containerId; ?>", {
width: "100%",
height: "800px",
pdfOpenParams: { view: "FitH" }
});
}
btn.textContent = "PDF 닫기";
isPdfOpen = true;
} else {
container.innerHTML = "";
container.style.display = "none";
btn.textContent = "첨부된 PDF 바로보기 (<?php echo $file['source']; ?>)";
isPdfOpen = false;
}
});
})();
</script>
<?php
}
}
}
?>
<!-- PDF 보기 끝 -->
파일은 필요 없습니다
게시글 목록
| 번호 | 제목 |
|---|---|
| 13945 | |
| 13943 | |
| 13939 | |
| 13932 | |
| 13931 | |
| 13923 | |
| 13911 | |
| 13906 | |
| 13891 | |
| 13884 | |
| 13873 | |
| 13861 |
댓글 작성
댓글을 작성하시려면 로그인이 필요합니다.
로그인하기