Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11You do not assign an existing HTML <canvas> element—or a canvas returned by html2canvas—to a canvas2pdf PDF context. Instead, create a PdfContext from a blob stream and replay the supported drawing operations on that context. If all you have is a finished bitmap, use a PDF workflow that accepts an image; the cited canvas2pdf examples do not document an API for attaching an arbitrary canvas bitmap.
Why a canvas cannot be assigned to the PDF context
A regular HTML canvas is a drawing surface whose completed content is represented as pixels. A canvas2pdf PdfContext, by contrast, records canvas-like drawing operations as PDF drawing calls. The documented pattern is to send the drawing commands to the PDF context in the first place, rather than to create a bitmap canvas and then transfer that canvas object into the context.
That distinction matters if your code currently uses html2canvas. Its callback gives you a rendered canvas, but the relevant canvas2pdf examples do not show a method such as ctx.addCanvas(canvas) or a way to assign that result to ctx. Do not treat the callback’s canvas as interchangeable with the PDF context.
Choose a workflow based on the input you have
- You have the drawing logic or scene: run the supported drawing commands against
PdfContext. This is the vector-oriented canvas2pdf workflow. - You have only a completed bitmap canvas: use a PDF library or workflow that accepts an image if raster output is acceptable. The sources here do not establish a canvas2pdf bitmap-adoption method.
The canvas2pdf README describes output as vector drawing calls in a PDF, rather than a rasterized canvas image. That is useful when your source can be represented by the operations supported by the context, but it is not the same as importing an already-rendered image.
#1 Best Overall
Create a PdfContext and replay your drawing commands
The core change is to replace the drawing target: use the PDF context as the target for supported calls. The following browser-style example follows the documented stream, context, completion, blob, and end sequence. It assumes the page has loaded blobStream, the canvas2pdf browser build, and a saveAs function.
const stream = blobStream();
const ctx = new canvas2pdf.PdfContext(stream);
// Replay the operations that create your drawing on the PDF context.
ctx.fillStyle = "yellow";
ctx.fillRect(100, 100, 100, 100);
ctx.stream.on("finish", function () {
const blob = ctx.stream.toBlob("application/pdf");
saveAs(blob, "example.pdf", true);
});
ctx.end();
The important part is not the sample rectangle; it is that fillStyle and fillRect are applied to ctx, not to an HTML canvas. Replace the example drawing with the supported operations that describe your own content.
What each step does
- Create the stream:
blobStream()supplies the stream used by the PDF context. - Create the PDF drawing target: pass that stream to
new canvas2pdf.PdfContext(stream). - Draw: issue your supported canvas-like drawing calls on
ctx. - Finish and consume the output: when the stream emits
finish, convert it to a Blob with the PDF MIME type and save or otherwise consume that Blob. - End the context: call
ctx.end()after issuing the drawing operations so the stream can finish.
The README also shows the module import form import PdfContext from "/src/canvas2pdf". In a browser-style build, examples may instead expose the constructor as canvas2pdf.PdfContext. Use the form that matches the build and version in your project; do not combine an import style and a global name without confirming both are available in your page.
Refactor code that currently draws on an HTML canvas
If existing code draws directly to a 2D canvas context, make the drawing logic reusable so it can draw to either target. The following is a structural example, not an additional canvas2pdf API:
Free tools Windows power users keep installed
One-click scans. No signup required.
function drawScene(target) {
target.fillStyle = "yellow";
target.fillRect(100, 100, 100, 100);
}
const stream = blobStream();
const pdfContext = new canvas2pdf.PdfContext(stream);
drawScene(pdfContext);
pdfContext.stream.on("finish", function () {
const blob = pdfContext.stream.toBlob("application/pdf");
saveAs(blob, "example.pdf", true);
});
pdfContext.end();
Here, drawScene receives a drawing target and issues calls on that target. You can pass a normal canvas 2D context when you want a canvas rendering, or a PdfContext when you want PDF drawing calls, provided the operations in the scene are supported by both. The code does not convert an existing canvas; it runs the drawing logic again against a different target.
For a larger application, keep layout and scene decisions separate from the code that selects the output target. Then the PDF path can replay the same scene description without depending on pixels already rendered by html2canvas. If you cannot recover or rerun the drawing operations because the bitmap is your only input, use an image-capable PDF route instead.
Know the method-support limits before converting a drawing
A canvas-like method name does not guarantee that every Canvas 2D operation is implemented by canvas2pdf. The project README specifically notes that arcTo is not implemented. It also documents a behavior to account for when issuing fills and strokes: consecutive fill() followed by stroke() only executes the fill.
- Audit the operations your drawing uses against the canvas2pdf version in your project.
- Where a method is not supported, decide whether you can express the scene with supported calls or need a different output path.
- Do not assume a visually equivalent HTML canvas result proves the same sequence will be reproduced by the PDF context.
- Check fill and stroke behavior explicitly if your artwork relies on both operations in sequence.
The available documentation establishes those named limitations, but does not provide a complete compatibility matrix here. Treat other Canvas 2D methods as requiring confirmation rather than assuming full API parity.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →If the only source is an html2canvas result
If an html2canvas callback has already produced a canvas and you no longer have the DOM scene or drawing operations, the documented canvas2pdf pattern does not provide an assignment step for that canvas. There are two practical paths:
- Recreate or replay the scene: return to the source page or drawing logic, extract the operations or scene data, and issue supported operations on
PdfContext. - Preserve the bitmap: use a PDF workflow that accepts an image and place the rendered image into the PDF. This produces raster content; it is not the vector replay described for canvas2pdf.
A community answer associated with the question mentions an html2canvas-plus-jsPDF image workflow as a raster screenshot approach. That is a separate workflow suggestion, not evidence that canvas2pdf accepts an html2canvas canvas object.
Troubleshooting common problems
“How do I assign the canvas to ctx?”
There is no assignment in the documented pattern. Create the PdfContext with a blob stream, then run the relevant drawing calls on it. If the canvas is already complete and only its pixels remain, switch to an image-accepting PDF workflow or recover the original drawing operations.
PdfContext is undefined
Check how the project is loaded. The module example imports PdfContext directly, while browser examples may use canvas2pdf.PdfContext. A mismatch between the installed build and the name used in the code can leave the constructor unavailable. Align the import or global reference with the build actually included.
Rank #4
The PDF is empty or appears unfinished
Confirm that the drawing calls target the PDF context, that ctx.end() is called after the drawing operations, and that the Blob is created in the stream’s finish handler. The documented example uses that completion event before converting the stream to an application/pdf Blob.
An operation is missing or the result differs
Check method support and the documented fill/stroke behavior. In particular, arcTo is called out as unimplemented, and a consecutive fill() then stroke() sequence only executes fill according to the README. Adapt the operations or choose a workflow suited to the source content.
The code works for the canvas but not for the PDF
The PDF context is not established as a drop-in implementation of every Canvas 2D feature. Keep the scene’s operations within the supported subset, and test the actual output for the drawing workload and build you use. The cited materials do not establish current release status or compatibility for a particular browser or runtime.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your real goal is to capture a web page as an image or PDF rather than to convert an existing canvas object, ScreenshotNeo is a separate website screenshot API and MCP server. It does not assign a canvas to canvas2pdf; it is an alternative for capturing a URL directly.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for request options. The same one-request pattern is available in Python and Node.js:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
- Cookie banners and consent interfaces, newsletter popups, and chat widgets are removed before the shot; each of those steps can be turned off.
- Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers say which page verdict applied and whether the shot was billed.
- An MCP server provides
take_screenshot,get_page_info, andcapture_pdftools for Claude, Cursor, and other MCP clients. - The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month without a card.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

