Background of the problem: business in the preview pdf file, the pdf to zoom in and out operations, if the frequency of operation is too fast or multiple execution page to display the contents of the pdf file is lost, the display is incomplete, the content is inverted and other phenomena. Open the console to find an error message: ERROR Error: Uncaught (in promise): Error: Cannot use the same canvas during multiple render() operations. use different canvas or Use different canvas or ensure previous operations were cancelled or completed.
Reason analysis: the meaning of the error may be the canvas tag in the display of pdf file content, pdf rendering errors, the problem may be in the scaling operation of the logic code in what operation caused.
Check the code found here to display the pdf file is not paged display, so in the scaling operation, go through all the canvas tags, and then the implementation of the pdf.getPage () this r function, re-modify the width and length of the canvasde rendering pdf. page.render (renderContext) is an asynchronous operation, traversing the canvas to modify the canvas rendering pdf may cause the last asynchronous rendering operation has not yet finished and start a new render, which will report an error resulting in pdf rendering errors.
pdfStreamRenderPage = (num) => { // A string of pdf 64-bit streams with zoom in/out rotation
if (self.pageRendering) {
self.pageNumPending = num;
} else {
const container = document.getElementById('thisCanvas1').getElementsByTagName('canvas');
// This traversal operation will result in an error
for (let i = 1; i <= container.length; i++) {
self.pageRendering = true;
self.pdfDoc.getPage(i).then((page) => {
const viewport = page.getViewport(self.scale, self.rotate);
container[i - 1].height = viewport.height;
container[i - 1].width = viewport.width;
const ctx = container[i - 1].getContext('2d');
const renderContext = {
canvasContext: ctx,
viewport
};
const renderTask = page.render(renderContext);
// You can wait here for rendering to finish before manipulating the next canvas
renderTask.promise.then(() => {
self.pageRendering = false;
if (self.pageNumPending !== null) {
renderPage(self.pageNumPending);
self.pageNumPending = null;
}
});
});
}
}
};
Optimize this traversal operation logic to wait for the previous renderTask.promise.then() canvas rendering to finish before executing the next canvas rendering operation.
Modified code:
const pdfStreamRenderPage = (num) => {
// A string of pdf 64-bit streams with zoom in/out rotation
if (self.pageRendering) {
self.pageNumPending = num;
} else {
const canvasElementMap = document.getElementById('thisCanvas1').getElementsByTagName('canvas');
const canvasElement = canvasElementMap[0]
const pageNum = 1
scalePdfCanvas(canvasElement, pageNum, canvasElementMap)
}
};
/**
* Scaling the contents of each pdf page
* @param canvasElement current page canvas
* @param num current page number
* @param canvasElementMap the set of all rendering pdf's canvas
*/
const scalePdfCanvas = (
canvasElement: HTMLCanvasElement,
num: number,
canvasElementMap: HTMLCollectionOf<HTMLCanvasElement>
) => {
self.pageRendering = true;
self.pdfDoc.getPage(num).then((page) => {
const viewport = page.getViewport(self.scale, self.rotate);
canvasElement.height = viewport.height;
canvasElement.width = viewport.width;
const ctx = canvasElement.getContext('2d');
// Render PDF page into canvas context
const renderContext = {
canvasContext: ctx,
viewport,
};
const renderTask = page.render(renderContext);
// Wait for rendering to finish
renderTask.promise.then(() => {
self.pageRendering = false;
num++;
if (num <= canvasElementMap.length) {
// scale next canvas
scalePdfCanvas(canvasElementMap[num-1], num, canvasElementMap)
}
if (self.pageNumPending !== null) {
// New page rendering is pending
pdfStreamRenderPage(self.pageNumPending);
self.pageNumPending = null;
}
});
});
}
Read More:
- PDF.js load PDF Error: Message: failed to fetch
- uniapp Use render Function Error: [Vue warn]: Error in beforeCreate hook: “TypeError: Cannot read property ‘_i‘ of
- JS: How to Solve split, join, toString Use error
- js: SyntaxError: Cannot use import statement outside a module
- [Solved] React Error: ReactDOM.render is no longer supported in React 18.
- [Solved] Nuxt Import qrcodejs2.js / QRCode.js Error: document is not defined
- [Vue warn]: Error in render: “TypeError: Cannot read properties of undefined
- [Vue warn]: Error in render: “TypeError: Cannot read properties of undefined
- [Solved] Pdfjs Preview PDF error: formaterror: bad fcheck in flat stream: 120, 239
- [Solved] Vue Error: template or render function not defined
- [Solved] Binding onclick event in JS: for loop: error uncaught typeerror: cannot set properties of undefined (setting ‘classname’)
- Solution to some map files in JS folder after Vue packaging (remove the map. JS file)
- Solution to build error in Vue project (error in static/JS)/vendor.xxxxx.js from UglifyJs)
- JS native implementation Promise.all
- [Solved] webpack Package Error: ERROR in multi ./src/main.js ./dist/bundle.js Module not found: Error: Can‘t resolv
- [Solved] Element Error: Error in render: TypeError: dateStr.match is not a function“
- @requestbody: How to Use or Not Use
- Vue a page is mounted to send multiple requests at the same time, and the loading is processed uniformly
- [Solved] JS Error: Uncaught TypeError: Cannot set properties of null (setting ‘innerHTML‘)
- [Solved] electron Use remote Error: Cannot read properties of undefined (reading ‘BrowserWindow‘)