I’m using turnjs 4 and pdfjs to create a pdf flipbook. Currently it’s working fine on initial rendering. But the problem is upon window resize or at the time of checking responsive of the page in browser causing flipbook break which automatically disappears by leaving blank space.
How to handle this problem specially on window resize event occurs.
I’m providing the implementation code below
class PDFFlipbook {
constructor(pdfUrl, containerClass) {
this.pdfUrl = pdfUrl;
this.container = document.querySelector(containerClass);
this.zoomLevel = 1.5; // Default zoom level
this.isZoomedIn = false; // Track zoom state
this.init();
}
async init() {
// Prepare the flipbook container
this.container.innerHTML = '';
const flipbook = document.createElement('div');
flipbook.className = 'flipbook';
this.container.appendChild(flipbook);
// Render each page of the PDF and add to flipbook
await this.renderPages(flipbook);
// Initialize the flipbook
this.initializeFlipbook();
// Setup click zoom control
this.setupClickZoom();
}
async renderPages(flipbook) {
flipbook.innerHTML = '';
// Load the PDF document
this.pdf = await pdfjsLib.getDocument(this.pdfUrl).promise;
const canvases = []; // Array to hold canvases for later processing
for (let pageNumber = 1; pageNumber <= this.pdf.numPages; pageNumber++) {
const page = await this.pdf.getPage(pageNumber);
const canvas = document.createElement('canvas');
canvas.className = 'page';
const context = canvas.getContext('2d');
const viewport = page.getViewport({ scale: this.zoomLevel });
canvas.width = viewport.width;
canvas.height = viewport.height;
await page.render({ canvasContext: context, viewport: viewport }).promise;
canvases.push(canvas); // Store canvas for later
}
// Now append all canvases to the flipbook
canvases.forEach(canvas => {
flipbook.appendChild(canvas);
});
}
initializeFlipbook() {
const resizeFlipbook = async () => {
let screenWidth = window.innerWidth;
let containerWidth, containerHeight;
// Get the first canvas to calculate the aspect ratio
const canvas = this.container.querySelector("canvas");
if (!canvas) return;
const aspectRatio = canvas.width / (canvas.height / 2);
// Adjust width based on screen size
if (screenWidth <= 480) {
containerWidth = screenWidth * 0.9;
} else if (screenWidth <= 768) {
containerWidth = screenWidth * 0.8;
} else {
containerWidth = screenWidth * 0.6;
}
containerHeight = containerWidth / aspectRatio;
const flipbookElement = $(this.container.querySelector('.flipbook'));
if (flipbookElement.data('done')) {
flipbookElement.turn('destroy');
}
// Set the container dimensions
flipbookElement.css({
width: containerWidth,
height: containerHeight,
});
flipbookElement.turn({
width: screenWidth <= 768 ? containerWidth / 2 : containerWidth,
height: containerHeight,
autoCenter: true,
duration: 1000,
elevation: 50,
gradients: true,
display: screenWidth <= 768 ? 'single' : 'double',
});
// Add CSS transitions for smooth zoom
flipbookElement.css({
transition: 'transform 0.5s ease-in-out',
transformOrigin: 'center center',
});
};
resizeFlipbook();
window.addEventListener('resize', () => {
clearTimeout(this.resizeTimeout);
this.resizeTimeout = setTimeout(() => {
resizeFlipbook();
}, 250);
});
}
setupClickZoom() {
const flipbookElement = this.container.querySelector('.flipbook');
flipbookElement.addEventListener('click', async (event) => {
event.preventDefault();
event.stopPropagation();
const { left, top, width, height } = flipbookElement.getBoundingClientRect();
const centralXStart = left + (width * 0.2);
const centralXEnd = left + (width * 0.8);
const centralYStart = top + (height * 0.2);
const centralYEnd = top + (height * 0.8);
const clickX = event.clientX;
const clickY = event.clientY;
if (clickX >= centralXStart && clickX <= centralXEnd && clickY >= centralYStart && clickY <= centralYEnd) {
if (this.isZoomedIn) {
this.zoomLevel = 1.5;
flipbookElement.style.transform = 'scale(1)'; // Zoom out
} else {
this.zoomLevel = 2.5;
flipbookElement.style.transform = 'scale(1.5)'; // Zoom in
}
this.isZoomedIn = !this.isZoomedIn;
}
});
}
}
document.addEventListener('DOMContentLoaded', () => {
const pdfUrls = [
'../assets/improve-everyday.pdf',
'../assets/sample1.pdf',
];
new PDFFlipbook(pdfUrls[0], 'section[data-component-variant="pdfBook-v1"] div.container div.grid div.page div.flipbook-container');
new PDFFlipbook(pdfUrls[1], 'section[data-component-variant="pdfBook-v1 topBar"] div.container div.grid div.page div.flipbook-container');
});
this is the html snippet
<section
data-component-set="basic"
data-component-group="oneCol"
data-component-variant="pdfBook-v1"
data-config-style=" "
data-config-style-variant=" "
class="--component full-bleed mediumColorBG">
<div class="container">
<div class="grid --oneCol _gap-2">
<div class="txtBox --textAlign _center">
<h2 class="title">Demo Title</h2>
<p class="--ellipsis _3">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab architecto dolorem eum illo
nihil rem soluta? Accusamus alias consectetur debitis earum ex iste perspiciatis quisquam
sint tempore, voluptatem. Recusandae, voluptatum.
</p>
</div>
<div class="page">
<div class="flipbook-container"></div>
</div>
</div>
</div>
</section>
while resizing the the window for checking responsiveness I’m getting the below error which is causing a problem for flipbook which disappears after.
I’m using the below turnjs code from turnjs.com – http://www.turnjs.com/lib/turn.min.js