You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
});

可能的原因与解决方案

  1. 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操作
            });
        });
    });
    
  2. 改用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操作
    }
    
  3. 确保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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 11:35:59