Autodesk Forge Viewer Api 无法在屏幕截图中加载标记
Autodesk Forge Viewer Api Cannot load markups inside screenshot
美好的一天,
我使用的是最新的 Autodesk Forge 查看器,我正在尝试截取同时呈现我的标记的屏幕截图。现在我的代码截取了一张没有任何标记的屏幕截图。下面是我的查看器代码。我正在加载标记核心和标记 Gui 扩展。注意 onDocumentLoadSuccess(viewerDocument) 中的“takeSnapshot(viewer)”函数。该函数在初始化函数之前定义。
function takeSnapshot(target){
$('#snipViewer').click( () => {
target.getScreenShot(1600, 920, (blobURL) => {
let snip = blobURL;
$('#sniplink').attr("href", snip);
$('#sniplink').html('Not Empty');
$('#sniplink').css({"background-image": `url(${blobURL})`});
});
});
}
//Autodesk Viewer Code
instance.data.showViewer = function showViewer(viewerAccessToken, viewerUrn){
localStorage.setItem("viewerAccessTokentoken", viewerAccessToken);
localStorage.setItem("viewerUrn", viewerUrn);
var viewer;
var options = {
env: 'AutodeskProduction',
api: 'derivativeV2',
getAccessToken: function(onTokenReady) {
var token = viewerAccessToken;
var timeInSeconds = 3600;
onTokenReady(token, timeInSeconds);
}
};
Autodesk.Viewing.Initializer(options, function() {
let htmlDiv = document.getElementById('forgeViewer');
viewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv);
let startedCode = viewer.start();
viewer.setTheme("light-theme");
viewer.loadExtension("Autodesk.CustomDocumentBrowser").then(() => {
viewer.loadExtension("Autodesk.Viewing.MarkupsCore");
viewer.loadExtension("Autodesk.Viewing.MarkupsGui");
});
if (startedCode > 0) {
console.error('Failed to create a Viewer: WebGL not supported.');
$("#loadingStatus").html("Failed to create a Viewer: WebGL not supported.");
return;
}
console.log('Initialization complete, loading a model next...');
});
var documentId = `urn:` + viewerUrn;
var derivativeId = `urn:` + instance.derivativeUrn;
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
function onDocumentLoadSuccess(viewerDocument) {
var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(viewerDocument, defaultModel);
takeSnapshot(viewer);
}
function onDocumentLoadFailure() {
console.error('Failed fetching Forge manifest');
$("#loadingStatus").html("Failed fetching Forge manifest.");
}
}
我已经读过这篇文章:https://forge.autodesk.com/blog/screenshot-markups
我试过使用这种方法,但说明对我来说非常不清楚。 <div style="width:49vw; height:100vh;display:inline-block;"><canvas id="snapshot" style="position:absolute;"></canvas><button onclick="snaphot();" style="position:absolute;">Snapshot!</button></div>
这里的 canvas 元素是做什么用的?当我在初始化函数或屏幕截图函数中加载标记扩展时,我是否应该 renderToCanvas() ?有什么方法可以实现 renderToCanvas() 而无需过多更改我已经在此处使用的内容吗?我不是查看器专家 API 所以如果你能帮助我,我将不胜感激,我是初学者,请不要跳过很多步骤。
非常感谢!
这里有一些在 Forge Viewer 中生成带标记的屏幕截图的更简化的逻辑,下面还有一些关于为什么需要这样做的更多解释:
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();
基本上,标记扩展只能将其标记(而不是底层 2D/3D 场景)渲染到现有的 <canvas>
元素中。这就是为什么这是一个多步骤过程:
- 您使用
viewer.getScreenShot
渲染底层 2D/3D 场景,获取包含屏幕截图图像数据的 blob URL
- 您创建了一个新的
<canvas>
元素
- 您将屏幕截图插入 canvas(在本例中,我们创建一个新的
Image
实例并使用 context.drawImage
将其渲染到 canvas)
- 您调用扩展程序的
renderToCanvas
,它将在屏幕截图图像 canvas 顶部 中呈现标记
美好的一天,
我使用的是最新的 Autodesk Forge 查看器,我正在尝试截取同时呈现我的标记的屏幕截图。现在我的代码截取了一张没有任何标记的屏幕截图。下面是我的查看器代码。我正在加载标记核心和标记 Gui 扩展。注意 onDocumentLoadSuccess(viewerDocument) 中的“takeSnapshot(viewer)”函数。该函数在初始化函数之前定义。
function takeSnapshot(target){
$('#snipViewer').click( () => {
target.getScreenShot(1600, 920, (blobURL) => {
let snip = blobURL;
$('#sniplink').attr("href", snip);
$('#sniplink').html('Not Empty');
$('#sniplink').css({"background-image": `url(${blobURL})`});
});
});
}
//Autodesk Viewer Code
instance.data.showViewer = function showViewer(viewerAccessToken, viewerUrn){
localStorage.setItem("viewerAccessTokentoken", viewerAccessToken);
localStorage.setItem("viewerUrn", viewerUrn);
var viewer;
var options = {
env: 'AutodeskProduction',
api: 'derivativeV2',
getAccessToken: function(onTokenReady) {
var token = viewerAccessToken;
var timeInSeconds = 3600;
onTokenReady(token, timeInSeconds);
}
};
Autodesk.Viewing.Initializer(options, function() {
let htmlDiv = document.getElementById('forgeViewer');
viewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv);
let startedCode = viewer.start();
viewer.setTheme("light-theme");
viewer.loadExtension("Autodesk.CustomDocumentBrowser").then(() => {
viewer.loadExtension("Autodesk.Viewing.MarkupsCore");
viewer.loadExtension("Autodesk.Viewing.MarkupsGui");
});
if (startedCode > 0) {
console.error('Failed to create a Viewer: WebGL not supported.');
$("#loadingStatus").html("Failed to create a Viewer: WebGL not supported.");
return;
}
console.log('Initialization complete, loading a model next...');
});
var documentId = `urn:` + viewerUrn;
var derivativeId = `urn:` + instance.derivativeUrn;
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
function onDocumentLoadSuccess(viewerDocument) {
var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(viewerDocument, defaultModel);
takeSnapshot(viewer);
}
function onDocumentLoadFailure() {
console.error('Failed fetching Forge manifest');
$("#loadingStatus").html("Failed fetching Forge manifest.");
}
}
我已经读过这篇文章:https://forge.autodesk.com/blog/screenshot-markups
我试过使用这种方法,但说明对我来说非常不清楚。 <div style="width:49vw; height:100vh;display:inline-block;"><canvas id="snapshot" style="position:absolute;"></canvas><button onclick="snaphot();" style="position:absolute;">Snapshot!</button></div>
这里的 canvas 元素是做什么用的?当我在初始化函数或屏幕截图函数中加载标记扩展时,我是否应该 renderToCanvas() ?有什么方法可以实现 renderToCanvas() 而无需过多更改我已经在此处使用的内容吗?我不是查看器专家 API 所以如果你能帮助我,我将不胜感激,我是初学者,请不要跳过很多步骤。
非常感谢!
这里有一些在 Forge Viewer 中生成带标记的屏幕截图的更简化的逻辑,下面还有一些关于为什么需要这样做的更多解释:
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();
基本上,标记扩展只能将其标记(而不是底层 2D/3D 场景)渲染到现有的 <canvas>
元素中。这就是为什么这是一个多步骤过程:
- 您使用
viewer.getScreenShot
渲染底层 2D/3D 场景,获取包含屏幕截图图像数据的 blob URL - 您创建了一个新的
<canvas>
元素 - 您将屏幕截图插入 canvas(在本例中,我们创建一个新的
Image
实例并使用context.drawImage
将其渲染到 canvas) - 您调用扩展程序的
renderToCanvas
,它将在屏幕截图图像 canvas 顶部 中呈现标记