Autodesk Forge Viewer Api Cannot load markups inside screenshot

Solution 1:

Here's a bit more simplified logic for generating screenshots with markups in Forge Viewer, with a bit more explanation on why it needs to be done this way below:

function getViewerScreenshot(viewer) {
    return new Promise(function (resolve, reject) {
        const screenshot = new Image();
        screenshot.onload = () => resolve(screenshot);
        screenshot.onerror = err => reject(err);
        viewer.getScreenShot(viewer.container.clientWidth, viewer.container.clientHeight, function (blobURL) {
            screenshot.src = blobURL;
        });
    });
}
function addMarkupsToScreenshot(viewer, screenshot) {
    return new Promise(function (resolve, reject) {
        const markupCoreExt = viewer.getExtension('Autodesk.Viewing.MarkupsCore');
        const canvas = document.createElement('canvas');
        canvas.width = viewer.container.clientWidth;
        canvas.height = viewer.container.clientHeight;
        const context = canvas.getContext('2d');
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.drawImage(screenshot, 0, 0, canvas.width, canvas.height);
        markupCoreExt.renderToCanvas(context, function () {
            resolve(canvas);
        });
    });
}
const screenshot = await getViewerScreenshot(viewer);
const canvas = await addMarkupsToScreenshot(viewer, screenshot);
const link = document.createElement('a');
link.href = canvas.toDataURL();
link.download = 'screenshot.png';
link.click();

Basically, the markups extension can only render its markups (and not the underlying 2D/3D scene) into an existing <canvas> element. That's why this is a multi-step process:

  1. You render the underlying 2D/3D scene using viewer.getScreenShot, getting a blob URL that contains the screenshot image data
  2. You create a new <canvas> element
  3. You insert the screenshot into the canvas (in this case we create a new Image instance and render it into the canvas using context.drawImage)
  4. You call the extension's renderToCanvas that will render the markups in the canvas on top of the screenshot image