Html2canvas: 使用 Leaflet 导出

创建于 2015-04-09  ·  21评论  ·  资料来源: niklasvh/html2canvas

有没有人尝试将 html2canvas 与传单一起使用。 我已经能够让 html2canvas 与谷歌地图一起使用,但我现在需要让它为传单工作,当我向左、向右、向上或向下平移地图时,我错过了传单中的一些图块。 我也不再得到我的覆盖。 我创建了一个粗略的 jsfiddle 来显示丢失的瓷砖问题。 还附上了我的代码的屏幕截图
missingtiles

https://jsfiddle.net/japiasente/7ybndo5L/

Needs More Information

最有用的评论

它需要一些丑陋的黑客才能让它工作。 这是一个没有任何修复的简单示例:

http://jsfiddle.net/djwbra47/

有几个问题:

  1. 圆形标记被剪裁为四分之一圆。 看起来 html2canvas 在应用任何转换之前正在剪切元素。 标记将以 0,0 为中心,没有任何变换,因此它被剪裁到在该位置可见的四分之一圆。 然后 html2canvas 将其转换为实际位置。 我通过将左边距和上边距设置为 0 而不是负数来修复它(因此整个标记将在 0,0 处可见),然后将转换调整相同的量。 (当然,然后在画布被抓取后将这些值更改回来。)
  2. 该行显示在错误的位置。 看起来 html2canvas 正在两次对 SVG 路径应用转换。 如果没有任何修复,这条线会显示在左上角太远。 如果您将其变换更改为 0,则它会在右下角显示相同的距离。 我必须将转换设置为原始值的一半才能使其正常工作。
  3. 平移地图时,切片会被裁剪到原始范围。 这与第 1 个问题相同:Leaflet 通过转换地图窗格来平移地图,并且 html2canvas 在应用该转换之前剪切图块。 要解决此问题,请将变换 X 和 Y 值添加到每个 img 的左侧和顶部值,然后将其变换设置为 0。
  4. 当您平移地图时,html2canvas 会在标记和线的顶部绘制图块,因此它们不再可见。 当您在数字 3 中进行更改时,此问题已修复,但我不明白为什么。 当元素的属性更新时,绘图顺序可能会发生变化?

这是固定版本:
http://jsfiddle.net/oo2yms1h/

还有一个问题我还没有解决:当您平移地图以使线靠近右边缘时,它不会出现在画布上。 但我猜这是转换前 html2canvas 剪辑的另一个结果。

还有一点需要注意:默认的传单标记是从 cdn.leaflet.com 托管的图像,它会给出 CORS 错误,这意味着它不会出现在画布上。 任何使用 html2canvas 的人都需要自己托管图标,或者切换到不同的标记样式。

JAPiasente,看起来我在 3 号中的修复可以适应您的磁贴和平移问题。 此外,您的标记是 SVG 路径,并且似乎遇到了与我在第 2 行中相同的双重转换问题,它们显示在左上角太远。 这是具有这些更改的版本:

https://jsfiddle.net/6tn0zy48/

一切都显示在正确的位置,除了标记被剪裁得比地图底部更远。 看起来这是我仍在研究的同一个问题。

所有21条评论

使用http://jsfiddle.net提供问题示例

它需要一些丑陋的黑客才能让它工作。 这是一个没有任何修复的简单示例:

http://jsfiddle.net/djwbra47/

有几个问题:

  1. 圆形标记被剪裁为四分之一圆。 看起来 html2canvas 在应用任何转换之前正在剪切元素。 标记将以 0,0 为中心,没有任何变换,因此它被剪裁到在该位置可见的四分之一圆。 然后 html2canvas 将其转换为实际位置。 我通过将左边距和上边距设置为 0 而不是负数来修复它(因此整个标记将在 0,0 处可见),然后将转换调整相同的量。 (当然,然后在画布被抓取后将这些值更改回来。)
  2. 该行显示在错误的位置。 看起来 html2canvas 正在两次对 SVG 路径应用转换。 如果没有任何修复,这条线会显示在左上角太远。 如果您将其变换更改为 0,则它会在右下角显示相同的距离。 我必须将转换设置为原始值的一半才能使其正常工作。
  3. 平移地图时,切片会被裁剪到原始范围。 这与第 1 个问题相同:Leaflet 通过转换地图窗格来平移地图,并且 html2canvas 在应用该转换之前剪切图块。 要解决此问题,请将变换 X 和 Y 值添加到每个 img 的左侧和顶部值,然后将其变换设置为 0。
  4. 当您平移地图时,html2canvas 会在标记和线的顶部绘制图块,因此它们不再可见。 当您在数字 3 中进行更改时,此问题已修复,但我不明白为什么。 当元素的属性更新时,绘图顺序可能会发生变化?

这是固定版本:
http://jsfiddle.net/oo2yms1h/

还有一个问题我还没有解决:当您平移地图以使线靠近右边缘时,它不会出现在画布上。 但我猜这是转换前 html2canvas 剪辑的另一个结果。

还有一点需要注意:默认的传单标记是从 cdn.leaflet.com 托管的图像,它会给出 CORS 错误,这意味着它不会出现在画布上。 任何使用 html2canvas 的人都需要自己托管图标,或者切换到不同的标记样式。

JAPiasente,看起来我在 3 号中的修复可以适应您的磁贴和平移问题。 此外,您的标记是 SVG 路径,并且似乎遇到了与我在第 2 行中相同的双重转换问题,它们显示在左上角太远。 这是具有这些更改的版本:

https://jsfiddle.net/6tn0zy48/

一切都显示在正确的位置,除了标记被剪裁得比地图底部更远。 看起来这是我仍在研究的同一个问题。

解决最后剩下的问题并不难,只需将变换设置为 0 并使用 left 和 top 代替。

我的简单示例已更新:
http://jsfiddle.net/oo2yms1h/1/

我对您的地图的修订修复:
https://jsfiddle.net/6tn0zy48/1/

我在 Chrome 中工作,我只是注意到我的修复在 Firefox 和 IE 中不起作用。 他们将转换样式指定为 translate 而不是 translate3d,并且我的代码假定它始终是 translate3d。 他们使用 translate 而不是 Chrome 中的 left 和 top 来定位图块。 此更新后的示例针对所有三种浏览器进行了修订。 瓷砖和标记图标在这三个中都有效,但我仍然无法让 SVG 路径显示在 Firefox 和 IE 中。

http://jsfiddle.net/oo2yms1h/3/

IE 需要 html2canvas.svg 才能显示该行,并且在 SVG 层上设置转换或左/顶部属性时它也不起作用。 此示例适用于 IE,几乎适用于 Firefox:

http://jsfiddle.net/oo2yms1h/5/

要在 Firefox 中显示该行,您还需要通过更改 #648 中提到的 html2canvas 来切换到 base64 编码:
https://github.com/niklasvh/html2canvas/pull/648/files

感谢您迄今为止的所有帮助。 现在唯一的最后一个问题是,如果我在它上面有一个 svg 覆盖,IE 不能很好地使用它。 地图和 svg 覆盖在 chrome 中运行良好。 有任何想法吗?

@CraigVA你太棒了。 我刚刚花了两天时间试图解决这个问题。 我希望我早些时候遇到过你的 jsfiddles。 谢谢!!!

我在使用@CraigVA解决方案时遇到了问题,如果我完全平移地图,叠加层将偏离图块的中心。

为了解决这个问题,我所做的只是一个 redraw() 函数,它将视图设置到海洋中的其他地方一秒钟,然后将视图设置回原来的位置。 工作正常。

function redraw() {
    var lat_tmp = map.getCenter().lat;
    var lng_tmp = map.getCenter().lng;
    map.setView([-66.22149259832975, -1.142578125]);
    setTimeout(function () {
        waitForTilesToLoad()
    }, 50000);
    map.setView([lat_tmp, lng_tmp]);
}

万一有人遇到这个并且有同样的问题。

嗨,感谢这个 hack,除了路径层和大 TileLayers 之外,它运行良好。

  • 如果路径图层(多边形/折线)的一部分超出了原始地图边界,则在我移动地图时它会被 html2canvas 裁剪。
    我在这里用更长的折线更新了您的代码http://jsfiddle.net/c8LL4qfo/ 。 尝试移动地图,您会看到画布中的线条被剪裁了。
    关于如何解决这个错误的任何想法?

  • 第二点:如果 tileLayers 太大,html2canvas 不会等待地图渲染。 即使使用 UseCors=true。 有什么方法可以等待 tileLayers 加载? 我正在考虑使用加载事件,但我不知道该怎么做。

谢谢

这仍然是v1.0.0的问题吗? 如果是这样,您能否在jsfiddle上分享一个示例。

我使用 React 解决了这个问题:传单组件在移动地图后被重置,保持最后一个中心和缩放级别的状态。 由于提供的地图是新地图,因此不再与 html2canvas 冲突。

好的,我在 jsfiddle 代码中进行了更新:http: //jsfiddle.net/2zkLkLxc/
V1.0.0 不再存在裁剪问题,但我们在移动地图时遇到了图标裁剪(随时)和切片裁剪的问题。
我试图删除瓷砖上的黑客,但它并没有改变任何东西。

这很奇怪,因为我的代码已经更新到 v.1.0.0 并且没有图标剪辑。

此问题已自动关闭,因为我们要求原作者提供更多信息的请求没有得到回应。 只有当前存在于问题中的信息,我们没有足够的信息来采取行动。 如果您有或找到我们需要的答案,请联系我们,以便我们进一步调查。

我有同样的问题,但我使用 Leaflet Map 而不是 Google Map。
代码如下

var transform=$(".leaflet-map-pane").css("transform");
如果(转换){
var c = transform.split(",");
var d = parseFloat(c[4]);
var h = parseFloat(c[5]);
$(".leaflet-map-pane").css({
“转换”:“无”,
“左”:d,
“顶部”:h
})
}
html2canvas(document.body).then(function(canvas){
$(".leaflet-map-pane").css({
左:0,
顶部:0,
“变换”:变换
})
} // 这里使用的是 html2canvas 1.0.0-alpha.9

@CraigVA 非常感谢!

我目前在stackoverflow上有一个关于剪辑问题的问题。 我正在使用传单 1.3.1。 如果有人可以为我提供一些指导,将不胜感激。 问题就在这里。

@niklasvh问题仍然存在:http: //jsfiddle.net/x3jzsg9b/4/

问题仍然存在: https ://jsfiddle.net/x512pgjt/269/

@amarandon @bomba1990

尝试从地图中删除去渲染器填充。 它对我有用。

map.getRenderer(map).options.padding = 0;

这很好用!

html2canvas(document.querySelector("#mapid"), {
allowTaint:真,
使用CORS:真
}).then(画布 => {
document.body.appendChild(画布)
});

此页面是否有帮助?
0 / 5 - 0 等级