Markup渲染至Canvas时的Safari潜在兼容性问题咨询
Forge Viewer MarkupExtension.renderToCanvas 在Safari浏览器中无法渲染标记的问题
我们遇到了一个仅在Safari浏览器(桌面端MacOS及移动端)出现的MarkupExtension潜在Bug。实现逻辑是用Viewer内置功能生成截图后,调用markupExtension.renderToCanvas方法将所有绘制的标记渲染到截图所在Canvas,再导出为Blob,该思路参考了官方相关实现。
此功能在Chrome、Firefox和Edge中均可正常工作,但在所有基于Safari的浏览器中,markupExtension.renderToCanvas无法将现有标记渲染到指定Canvas,且无任何可见报错。想确认是否存在已知问题,或是实现代码有误?
以下是处理该任务的代码框架(已省略成功执行的截图部分):
const canvas = document.getElementById('someId'); const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, width, height); ctx.drawImage(screenshotFromViewer, 0, 0, width, height); markupExtension.renderToCanvas(ctx, () => { // callback: markups should be rendered to canvas });
可能的原因与解决方案
Safari的Canvas异步渲染特性
Safari对Canvas的2D上下文处理存在异步特性,当调用renderToCanvas时,当前Canvas上下文可能还未完成截图的绘制操作,导致标记渲染被覆盖或未执行。可以通过requestAnimationFrame确保截图绘制完成后再渲染标记:const canvas = document.getElementById('someId'); const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, width, height); requestAnimationFrame(() => { ctx.drawImage(screenshotFromViewer, 0, 0, width, height); requestAnimationFrame(() => { markupExtension.renderToCanvas(ctx, () => { // 后续导出Blob操作 }); }); });改用MarkupExtension内部Canvas绘制
Forge Viewer的MarkupExtension在Safari中存在渲染时序问题,可通过获取其内部Canvas直接绘制到目标Canvas上替代renderToCanvas调用:const canvas = document.getElementById('someId'); const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, width, height); ctx.drawImage(screenshotFromViewer, 0, 0, width, height); const markupCanvas = markupExtension.getCanvas(); if (markupCanvas) { ctx.drawImage(markupCanvas, 0, 0, width, height); // 直接执行后续导出Blob操作 }确保Canvas尺寸完全匹配
Safari对Canvas尺寸不匹配的容错性较低,需显式设置目标Canvas宽高与截图尺寸一致:const canvas = document.getElementById('someId'); canvas.width = width; canvas.height = height; const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, width, height); ctx.drawImage(screenshotFromViewer, 0, 0, width, height); markupExtension.renderToCanvas(ctx, () => { // 后续操作 });
内容的提问来源于stack exchange,提问作者user4697008
相关产品推荐
相关产品推荐

