Skip to content

Commit

Permalink
Removed shifted layer in snapshot (#1530)
Browse files Browse the repository at this point in the history
  • Loading branch information
allyoucanmap authored and offtherailz committed Mar 9, 2017
1 parent 8e8f79e commit 55b5b62
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 8 deletions.
57 changes: 50 additions & 7 deletions web/client/components/map/leaflet/snapshot/GrabMap.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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,
Expand Down Expand Up @@ -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();
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ describe("test the Leaflet Preview component", () => {
// emulate empty map
document.body.innerHTML = '<div><div id="snap"></div>' +
'<div id="map" style="width:100%; height:100%"><canvas></canvas>' +
'<div class="leaflet-tile-pane"><div class="leaflet-layer"></div></div>' +
'<div class="leaflet-map-pane">' +
'<div class="leaflet-tile-pane"><div class="leaflet-layer"></div></div>' +
'</div>' +
'</div></div>';
setTimeout(done);
});
Expand Down

0 comments on commit 55b5b62

Please sign in to comment.