问题描述
我们目前已将具有多个标记层(使用自定义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
之前,仔细检查标记列表。