first commit 2
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
(function($) {
|
||||
"use strict";
|
||||
|
||||
if (typeof window.initEbookModule === 'function') {
|
||||
return;
|
||||
}
|
||||
|
||||
window.initEbookModule = function(moduleId, pdfUrl, config) {
|
||||
var $module = $('#' + moduleId);
|
||||
if (!$module.length || !pdfUrl) return;
|
||||
|
||||
var pdfDoc = null;
|
||||
var pageCount = 0;
|
||||
var currentScale = 1.0;
|
||||
var initialLoadCount = 6;
|
||||
var isInitialized = false;
|
||||
var loadedPageCount = 0;
|
||||
var renderedCount = 0;
|
||||
|
||||
var $flipbook = $module.find('.flipbook');
|
||||
var $loadingOverlay = $module.find('.ebook-loading-overlay');
|
||||
var $loadingText = $module.find('.loading-text');
|
||||
var $viewport = $module.find('.flipbook-viewport');
|
||||
var $controls = $module.find('.ebook-controls');
|
||||
var $totalPages = $module.find('.total-pages');
|
||||
var $loadedPages = $module.find('.loaded-pages');
|
||||
var $pageInput = $module.find('.page-input');
|
||||
var $totalPagesWrap = $module.find('.total-pages-wrap');
|
||||
var $alertMsg = $module.find('.page-loading-alert');
|
||||
|
||||
function startEbookProcess() {
|
||||
if ($flipbook.turn('is')) {
|
||||
$flipbook.turn('destroy');
|
||||
}
|
||||
$flipbook.empty();
|
||||
$loadingOverlay.show();
|
||||
$viewport.add($controls).addClass('loading');
|
||||
|
||||
var availableWidth = $viewport.width() || config.width || 922;
|
||||
var availableHeight = $viewport.height() || config.height || 600;
|
||||
|
||||
var bookWidth, bookHeight;
|
||||
|
||||
function renderAllPages(pdf) {
|
||||
pdfDoc = pdf;
|
||||
pageCount = pdf.numPages;
|
||||
$totalPages.text(pageCount);
|
||||
$pageInput.attr('max', pageCount);
|
||||
|
||||
pdf.getPage(1).then(function(page) {
|
||||
var viewport = page.getViewport({ scale: 1 });
|
||||
var pageRatio = viewport.width / viewport.height;
|
||||
var bookRatio = pageRatio * 2;
|
||||
|
||||
bookWidth = availableWidth;
|
||||
bookHeight = bookWidth / bookRatio;
|
||||
|
||||
if (bookHeight > availableHeight) {
|
||||
bookHeight = availableHeight;
|
||||
bookWidth = bookHeight * bookRatio;
|
||||
}
|
||||
|
||||
var initialPromises = [];
|
||||
var loadLimit = Math.min(pageCount, initialLoadCount);
|
||||
|
||||
for (var i = 1; i <= loadLimit; i++) {
|
||||
initialPromises.push(renderPage(i, bookWidth, bookHeight, true, loadLimit));
|
||||
}
|
||||
|
||||
Promise.all(initialPromises).then(function(pages) {
|
||||
pages.forEach(function(pageDiv) {
|
||||
$flipbook.append(pageDiv);
|
||||
});
|
||||
|
||||
initTurnJs(bookWidth, bookHeight);
|
||||
isInitialized = true;
|
||||
loadedPageCount = loadLimit;
|
||||
updatePageDisplay();
|
||||
|
||||
$loadingOverlay.fadeOut(500);
|
||||
$viewport.add($controls).removeClass('loading');
|
||||
|
||||
if (pageCount > initialLoadCount) {
|
||||
loadRemainingPages(initialLoadCount + 1, bookWidth, bookHeight);
|
||||
} else {
|
||||
updatePageDisplay(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (pdfDoc) {
|
||||
run(pdfDoc);
|
||||
} else {
|
||||
pdfjsLib.getDocument(pdfUrl).promise.then(renderAllPages);
|
||||
}
|
||||
}
|
||||
|
||||
function loadRemainingPages(pageNum, bookWidth, bookHeight) {
|
||||
if (pageNum > pageCount) {
|
||||
updatePageDisplay(true);
|
||||
return;
|
||||
}
|
||||
renderPage(pageNum, bookWidth, bookHeight, false).then(function(pageDiv) {
|
||||
if ($flipbook.turn('is')) {
|
||||
$flipbook.turn('addPage', pageDiv, pageNum);
|
||||
}
|
||||
loadedPageCount = pageNum;
|
||||
updatePageDisplay();
|
||||
loadRemainingPages(pageNum + 1, bookWidth, bookHeight);
|
||||
});
|
||||
}
|
||||
|
||||
function updatePageDisplay(isComplete = false) {
|
||||
if (isComplete) {
|
||||
$totalPagesWrap.hide();
|
||||
$loadedPages.text(pageCount);
|
||||
} else {
|
||||
$loadedPages.text(loadedPageCount);
|
||||
$totalPagesWrap.show();
|
||||
}
|
||||
}
|
||||
|
||||
function renderPage(num, bookWidth, bookHeight, isInitial, loadLimit) {
|
||||
return pdfDoc.getPage(num).then(function(page) {
|
||||
var viewport = page.getViewport({ scale: 1.5 });
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
var pageWidth = bookWidth / 2;
|
||||
var pageHeight = bookHeight;
|
||||
var scaleX = pageWidth / viewport.width;
|
||||
var scaleY = pageHeight / viewport.height;
|
||||
var fitScale = Math.max(scaleX, scaleY);
|
||||
var fitViewport = page.getViewport({ scale: fitScale });
|
||||
|
||||
canvas.height = pageHeight;
|
||||
canvas.width = pageWidth;
|
||||
|
||||
var pageDiv = $('<div />').append(canvas);
|
||||
|
||||
var renderContext = { canvasContext: ctx, viewport: fitViewport };
|
||||
|
||||
return page.render(renderContext).promise.then(function() {
|
||||
if (isInitial) {
|
||||
renderedCount++;
|
||||
var percent = Math.round((renderedCount / loadLimit) * 100);
|
||||
$loadingText.text('Loading... (' + percent + '%)');
|
||||
}
|
||||
return pageDiv;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function initTurnJs(bookWidth, bookHeight) {
|
||||
if (typeof $flipbook.turn !== 'function') return;
|
||||
if ($flipbook.turn('is')) $flipbook.turn('destroy');
|
||||
|
||||
$flipbook.turn({
|
||||
width: bookWidth,
|
||||
height: bookHeight,
|
||||
autoCenter: true,
|
||||
gradients: true,
|
||||
acceleration: true,
|
||||
elevation: 50,
|
||||
display: 'double',
|
||||
pages: pageCount,
|
||||
when: {
|
||||
turned: function(event, page, view) {
|
||||
$pageInput.val(page);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
startEbookProcess();
|
||||
|
||||
// 이벤트 핸들러 (한 번만 등록)
|
||||
$module.find('#prev-btn, .nav-prev').off().on('click', function() { $flipbook.turn('previous'); });
|
||||
$module.find('#next-btn, .nav-next').off().on('click', function() { $flipbook.turn('next'); });
|
||||
$pageInput.off().on('change keyup', function(e) {
|
||||
if (e.type === 'keyup' && e.keyCode !== 13) return;
|
||||
var page = parseInt($(this).val());
|
||||
if (page > 0 && page <= pageCount) $flipbook.turn('page', page);
|
||||
});
|
||||
function updateZoom() {
|
||||
$viewport.css('transform', 'scale(' + currentScale + ')');
|
||||
$module.find('.zoom-level').text(Math.round(currentScale * 100) + '%');
|
||||
}
|
||||
$module.find('#zoom-in-btn').off().on('click', function() { if (currentScale < 2.0) { currentScale += 0.2; updateZoom(); } });
|
||||
$module.find('#zoom-out-btn').off().on('click', function() { if (currentScale > 0.6) { currentScale -= 0.2; updateZoom(); } });
|
||||
$module.find('#zoom-reset-btn').off().on('click', function() { currentScale = 1.0; updateZoom(); });
|
||||
$module.find('#dark-mode-btn').off().on('click', function() {
|
||||
var currentTheme = $module.attr('data-theme');
|
||||
var newTheme = currentTheme === 'light' ? 'dark' : 'light';
|
||||
$module.attr('data-theme', newTheme);
|
||||
$(this).find('i').toggleClass('fa-sun fa-moon');
|
||||
});
|
||||
$module.find('#print-btn').off().on('click', function() {
|
||||
var $iframe = $module.find('iframe');
|
||||
$iframe.attr('src', pdfUrl);
|
||||
$iframe.on('load', function() {
|
||||
try { this.contentWindow.print(); }
|
||||
catch (e) { window.open(pdfUrl, '_blank').print(); }
|
||||
});
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
||||
Reference in New Issue
Block a user