autodesk-viewerautodeskautodesk-bim360

How to get a viewer screenshot with BIM360 Pushpins and markups from MarkupsCore Extension?


I want to get a viewer screenshot with pushpins made with Autodesk.BIM360.Extension.PushPin and markups made with Autodesk.Viewing.MarkupsCore.

This related question describes how it's done with canvas and draw image, and other question do the same and even has a CodePen, but the markups are displaced:

Real:

img1

Image:

img2

So I'm searching through other methods.

getScreenshot method documentation:

docs

Is this overlayRenderer that I'm looking for? If it is, how do I configure it to get the pushpins and markups?

EDIT: I have already seen the html2canvas library, and the markups are also in the wrong position.


Solution

  • Solved with html2canvas, the previous attempts with this lib failed because:

    First try: Screenshot the whole viewer div, that's supposed to get pushpins and markups, but markups went misplaced.

    Second try: Screenshot the whole viewer div, but exclude markups passing an identifier to html2canvas config, then create another image with markupsExt.generateData(), and draw these two images into a temporary created canvas. This attempt is a little tricky because it's the same as solution, the difference is that I triggered all my next events inside svgimage.onload function, and with this approach, don't know why, markups were not even drawn.

    So the solution is wrap the whole logic into a function returning a promise, and resolve the generated image.

    Code:

                    const takeImg = () => {
                        return new Promise((resolve, reject) => {
                            html2canvas(
                                document.getElementById("mainViewerDiv"),
                                {
                                    ignoreElements: (element) =>
                                        element.getAttribute(
                                            "layer-order-id"
                                        ) === "markups-svg",
                                }
                            ).then((canvas) => {
                                canvas.toBlob(
                                    async function (blob) {
                                        const viewerImg = new Image();
                                        const viewerImgUrl =
                                            URL.createObjectURL(blob);
                                        viewerImg.src = viewerImgUrl;
                                        viewerImg.onload = function () {
                                            const newCanvas =
                                                document.createElement(
                                                    "canvas"
                                                );
                                            newCanvas.width = viewerImg.width;
                                            newCanvas.height = viewerImg.height;
                                            const svgImg = new Image();
    
                                            const svgString =
                                                this.mk_ext.generateData();
    
                                            const svgBlob = new Blob(
                                                [svgString],
                                                {type: "image/svg+xml",});
                                            const svgUrl =
                                                URL.createObjectURL(svgBlob);
                                            svgImg.src = svgUrl;
                                            svgImg.onload = async function () {
                                                const ctx =
                                                    newCanvas.getContext("2d");
                                                ctx.drawImage(viewerImg, 0, 0);
                                                ctx.drawImage(svgImg, 0, 0);
    
                                                resolve(
                                                    newCanvas.toDataURL(
                                                        "image/png"
                                                    )
                                                );
                                            };
                                        }.bind(this);
                                    }.bind(this)
                                );
                            });
                        });
                    };