【问题标题】:html2canvas wait for images to loadhtml2canvas 等待图片加载
【发布时间】:2014-07-27 19:13:47
【问题描述】:

我遇到这个问题已经有一段时间了,但我似乎找不到解决方案。

我正在使用最新的 html2canvas js 插件对使用 flotcharts 制作的图表进行截图,然后通过隐藏输入提交 base64 截图。问题是带有图表的 div 也有一些图像,并且 html2canvas 在加载图像之前返回一个 base64 字符串。我可以在提交上放置一个 setTimeout 直到它们被加载,但显然 chrome 打开了我作为弹出窗口提交的页面(这真的不行,因为我们的客户不知道如何允许弹出窗口)。 所以这是我尝试过的,但图像没有预加载(因为 html2canvas 的异步性质)

function getPNGBase64forHtml($container) {
    var imageString;

    html2canvas($container, {
        useCORS: true,
        onrendered: function(canvas) {
            imageString = canvas.toDataURL('image/png');
        }
    });

    return imageString;
}

还有这个(这工作正常,但它不会及时加载图像):

function getPNGBase64forHtml($container) {
    var h2canvas = html2canvas($container);
    var queue = h2canvas.parse();
    var canvas = h2canvas.render(queue);

    return canvas.toDataURL('image/png');
}

所以问题在于等待图像加载到 html2canvas 中,然后执行我的其余内容。 如果有人可以请帮助,那将非常感激,我向各位好心的先生们和女士们鞠躬! :)

编辑

这是我捕获的部分的 html,这一切都在一个打印容器 div 中。时间线预测中的箭头(仅显示一个)没有被捕获,因为它是一个图像,其他一切都会:

<div id="timeline-outer-container">
    <div id="timeline-container" class="flot-container">
        <div id="timeline-chart" class="flot-chart">
            <canvas class="flot-base" width="888" height="335" ></canvas>
            <div class="flot-text" >
                <div class="flot-x-axis flot-x1-axis xAxis x1Axis">
                    <div class="flot-tick-label tickLabel" >Q1</div>
                    <div class="flot-tick-label tickLabel">Q2</div>
                    ...
                </div>
                <div class="flot-y-axis flot-y1-axis yAxis y1Axis">
                    <div class="flot-tick-label tickLabel">75</div>
                    <div class="flot-tick-label tickLabel">100</div>
                    ...
                </div>
            </div>
            <canvas class="flot-overlay" width="888" height="335"></canvas>
            <div class="axis-label xaxis">Zeitraum</div>
            <div class="axis-label yaxis rotate-90">Anzahl</div>
            <div id="zoom-out-button" class="timeline-zoom-button"><i class="fa fa-zoom-out"></i></div>
            <div id="zoom-in-button" class="timeline-zoom-button"><i class="fa fa-zoom-in"></i></div>
            <div id="zoom-default-button" class="timeline-zoom-button"><i class="fa fa-repeat"></i></div>
        </div>
    </div>
</div>

<div id="timeline-prognose">
    <img id="timeline-arrow-up" class="timeline-arrows" src="/portal//images/arrows/up.png" alt="">
    <img id="timeline-arrow-down" class="timeline-arrows" src="/portal//images/arrows/down.png" alt="">
</div>

【问题讨论】:

  • 带有图表的 div 也有一些图像?显示截图或你有图表的代码:)
  • @martinezjc 我根据需要添加了 div 结构(稍微清除了不必要的样式等),但从我所看到的来看,图表不是问题。
  • 所以问题是没有显示箭头图像?
  • @martinezjc 是的,问题是图像(箭头)渲染速度不够快,我需要等待图像,但它们由 html2canvas 异步处理

标签: javascript image asynchronous wait html2canvas


【解决方案1】:

因此,由于您使用的是远程图像,因此您可以使用以下修复程序在您的脚本中进行一些修改:

function getPNGBase64forHtml() {
    var imageString;

    html2canvas(document.body, {
        useCORS: true,
        logging : true, //Enable log (use Web Console for get Errors and Warnings)
        proxy :"html2canvasproxy.php",
        onrendered: function(canvas) {
            var img = new Image();
            img.onload = function() {
                img.onload = null;
                document.body.appendChild(img);
            };

            img.onerror = function() {
                img.onerror = null;
                if(window.console.log) {
                    window.console.log("Not loaded image from canvas.toDataURL");
                } else {
                    alert("Not loaded image from canvas.toDataURL");
                }
            };

            imageString = canvas.toDataURL('image/png');
        }
    });

    return imageString;
}

如果您使用 php,则代理设置必须使用以下脚本:html2canvas-php-proxy

否则,对于 .NET 项目,您可以使用这些脚本资源:

html2canvas proxy with asp-classic - vb html2canvas proxy with asp.net - csharp

如果您决定使用本地图像,则不会出现此错误。

希望它对你有用,这里是这个 html2canvas 错误https://github.com/niklasvh/html2canvas/issues/145的原始线程

【讨论】:

  • 图像是本地的,usecors 标志不是必需的,我只是在测试一些东西,所以问题是我需要等待图像或以某种方式预加载它们
  • 在 onrendered 变量中设置画布处理告诉它在渲染所有图像后处理它。我使用这个库的方式和这个答案一样。
猜你喜欢
  • 1970-01-01
  • 2012-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-08
  • 2012-11-05
相关资源
最近更新 更多