使用多层伪造MarkupUtils renderToCanvas?

问题描述

我们目前已将具有多个标记层(使用自定义DrawMode创建)的PDF加载到Forge查看器中,每个层的可见性均可切换。

我们希望使用户能够打印他们当前看到的内容(带有分层标记的PDF)。我能够找到提供潜在打印解决方案的帖子(使用canvas,getScreenshot和MarkupUtils renderToCanvas)。 示例示例:Autodesk Forge get screenshot with markups

解决方案起初看起来效果很好,但我注意到我们只有一个标记层被渲染到画布上(看似最后添加了一层),其他层被忽略了。

所有标记均已加载并且在屏幕上可见。另外,如果我隐藏了该层,它仍然会打印。

是否有任何方法可以使用renderToCanvas从所有已加载的标记添加标记? 或任何潜在的已知解决方法

任何帮助表示赞赏。预先感谢。

我编写的功能正常的代码片段(但仅加载最近添加的图层)。

export const printViewerToPDF = (markupscore: Markupscore,jsPDF: any) => {
    // Create new image
    var screenshot = new Image();

    // Get the canvas element
    var canvas = document.getElementById('snapshot') as HTMLCanvasElement;

    // Fit canvas to match viewer
    if (canvas) {
        canvas.width = markupscore.bounds.width;
        canvas.height = markupscore.bounds.height;

        // Create a context
        var ctx = canvas.getContext('2d');

        // Clear
        if (ctx) {
            ctx.clearRect(0,canvas.width,canvas.height);
            ctx.drawImage(screenshot,canvas.height);
        }

        // Screenshot viewer and render to canvas
        markupscore.viewer.getScreenShot(canvas.width,canvas.height,function(
            blobUrl: any,) {
            screenshot.onload = function() {
                if (ctx) {
                    ctx.drawImage(screenshot,0);
                }
            };

            screenshot.src = blobUrl;
        });

        // Render markup to canvas
        setTimeout(function() {
            markupscore.renderToCanvas(ctx,function() {
                var pdf = new jsPDF('l','px',[canvas.height,canvas.width]);
                pdf.addImage(ctx!.canvas,canvas.height);
                pdf.save(Date.Now().toString() + '.pdf');
            });
        },300);
    }
};

解决方法

这是renderToCanvas方法的样子(您可以在https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/extensions/Markup/Markup.js中找到它):

MarkupsCore.prototype.renderToCanvas = function(context,callback,renderAllMarkups) {

        var width = this.bounds.width;
        var height = this.bounds.height;
        var viewBox = this.getSvgViewBox(width,height);
        var numberOfScreenshotsTaken = 0;
        var markups = [];
        var layer;

        var onMarkupScreenshotTaken = function () {
            if (callback && (++numberOfScreenshotsTaken === markups.length)) {
                callback();
            }
        }.bind(this);

        if (renderAllMarkups) {
            var svgKeys = Object.keys(this.svg.childNodes);
            var layersKeys = Object.keys(this.svgLayersMap);

            // Append only markups that their parent layer is contained inside the svg main container.
            for (var i = 0; i < svgKeys.length; i++) {                
                for (var j = 0; j < layersKeys.length; j++) {
                    layer = this.svgLayersMap[layersKeys[j]];
                    if (this.svg.childNodes[svgKeys[i]] === layer.svg) {
                        markups = markups.concat(layer.markups);
                    }
                }
            }
        } else {
            layer = this.svgLayersMap[this.activeLayer] || this.editModeSvgLayerNode;
            markups = layer.markups;
        }

        if (markups.length === 0) {
            callback();
        } else {
            markups.forEach(function(markup) {
                markup.renderToCanvas(context,viewBox,width,height,onMarkupScreenshotTaken);
            });
        }
    };

如您所见,如果未定义第三个参数或将其设置为false,则仅会显示 active 层中的标记。如果将第3个参数设置为true,则应渲染所有图层的标记。

尝试自己进入该方法,并在最后为列表中的每个项目调用markup.renderToCanvas之前,仔细检查标记列表。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...