From 04d113cfe594e417fb33f345174b3451eb4cd06d Mon Sep 17 00:00:00 2001 From: allyoucanmap Date: Wed, 8 Mar 2017 16:36:54 +0100 Subject: [PATCH] Removed shifted layer in snapshot --- .../map/leaflet/snapshot/GrabMap.jsx | 57 ++++++++++++++++--- .../snapshot/__tests__/Preview-test.jsx | 4 +- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/web/client/components/map/leaflet/snapshot/GrabMap.jsx b/web/client/components/map/leaflet/snapshot/GrabMap.jsx index 588058f565..c2e1694032 100644 --- a/web/client/components/map/leaflet/snapshot/GrabMap.jsx +++ b/web/client/components/map/leaflet/snapshot/GrabMap.jsx @@ -136,24 +136,39 @@ let GrabLMap = React.createClass({ // get all the informations needed to snap svg before let svgs = this.mapDiv.getElementsByTagName("svg"); - let svg = svgs && svgs[0]; + let svg = svgs && svgs[0] && svgs[0].cloneNode(true); + let svgOffsetX; + let svgOffsetY; let svgH; let svgW; let svgString; if (svg && svg.outerHTML) { + svgOffsetX = svgs[0] ? svgs[0].getBoundingClientRect().left : 0; + svgOffsetY = svgs[0] ? svgs[0].getBoundingClientRect().top : 0; svgString = svgs[0].outerHTML; svgW = svg.getAttribute("width"); svgH = svg.getAttribute("height"); + svg.setAttribute("style", ""); } let left = 0; if (leftString) { left = parseInt( leftString.replace('px', ''), 10); } - const tilePane = this.mapDiv.getElementsByClassName("leaflet-tile-pane"); - if (tilePane && tilePane.length > 0) { - let layers = [].slice.call(tilePane[0].getElementsByClassName("leaflet-layer"), 0); - layers.sort(function compare(a, b) { + // get pan position from translate 3d + let leafletPane = this.mapDiv.getElementsByClassName("leaflet-map-pane"); + let panPosition = leafletPane && leafletPane[0] && leafletPane[0].style && leafletPane[0].style.transform ? leafletPane[0].style.transform.replace(/\(|\)|translate3d/g, '').split('px, ') : ['0', '0']; + panPosition = [Number.parseFloat(panPosition[0]), Number.parseFloat(panPosition[1])]; + let tilePane = this.mapDiv.getElementsByClassName("leaflet-tile-pane"); + // clone to change style attributes + let tilePaneClone = tilePane && tilePane[0].cloneNode(true); + // bring back to hide + tilePaneClone.style.zIndex = -9999; + // append to prevent html2canvas errors + document.body.appendChild(tilePaneClone); + if (tilePaneClone) { + let layers = [].slice.call(tilePaneClone.getElementsByClassName("leaflet-layer"), 0); + layers.sort(function(a, b) { return Number.parseFloat(a.style.zIndex) - Number.parseFloat(b.style.zIndex); }); let canvas = this.getCanvas(); @@ -162,9 +177,27 @@ let GrabLMap = React.createClass({ return; } context.clearRect(0, 0, canvas.width, canvas.height); + + // remove transform style from every tile images and add left top attributes + let resetLayerStyles = function(l) { + for (let i = 0; i < l.children.length; i++) { + if (l.children[i]) { + for (let j = 0; j < l.children[i].children.length; j++) { + if (l.children[i].children[j] && l.children[i].children[j].tagName === 'IMG') { + l.children[i].children[j].style.position = 'absolute'; + l.children[i].children[j].style.left = l.children[i].children[j].getBoundingClientRect().left + left + panPosition[0] + 'px'; + l.children[i].children[j].style.top = l.children[i].children[j].getBoundingClientRect().top + panPosition[1] + 'px'; + l.children[i].children[j].style.transform = 'none'; + } + } + } + } + }; + let queue = layers.map((l) => { let newCanvas = this.refs.canvas.cloneNode(); newCanvas.width = newCanvas.width + left; + resetLayerStyles(l); return html2canvas(l, { // you have to provide a canvas to avoid html2canvas to crop the image canvas: newCanvas, @@ -196,19 +229,29 @@ let GrabLMap = React.createClass({ }); let finialize = () => { + // remove cloned panel from body + document.body.removeChild(tilePaneClone); + this.props.onStatusChange("READY", this.isTainted(finalCanvas)); this.props.onSnapshotReady(canvas, null, null, null, this.isTainted(finalCanvas)); }; if (svg) { let svgCanv = document.createElement('canvas'); - svgCanv.setAttribute("width", svgW); + svgOffsetX = svgOffsetX ? svgOffsetX : 0; + svgOffsetY = svgOffsetY ? svgOffsetY : 0; + svgCanv.setAttribute("width", Number.parseFloat(svgW) + left); svgCanv.setAttribute("height", svgH); canvg(svgCanv, svgString, { + ignoreMouse: true, + ignoreAnimation: true, + ignoreDimensions: true, ignoreClear: true, + offsetX: svgOffsetX, + offsetY: svgOffsetY, renderCallback: () => { let ctx = finalCanvas.getContext('2d'); - ctx.drawImage(svgCanv, -1 * (svgW - finalCanvas.width) / 2, -1 * (svgH - finalCanvas.height) / 2); + ctx.drawImage(svgCanv, -1 * left, 0); finialize(); } }); diff --git a/web/client/components/map/leaflet/snapshot/__tests__/Preview-test.jsx b/web/client/components/map/leaflet/snapshot/__tests__/Preview-test.jsx index 78a36e97da..c2f1904fdd 100644 --- a/web/client/components/map/leaflet/snapshot/__tests__/Preview-test.jsx +++ b/web/client/components/map/leaflet/snapshot/__tests__/Preview-test.jsx @@ -16,7 +16,9 @@ describe("test the Leaflet Preview component", () => { // emulate empty map document.body.innerHTML = '
' + '
' + - '
' + + '
' + + '
' + + '
' + '
'; setTimeout(done); });