2015-04-04 64 views
5

我有一些有趣的CSS/JavaScript問題。我正在構建一個用戶友好的網絡地圖,其中包括自願提供的地理信息,並需要能夠以多種紙張尺寸打印,最多可以張貼海報尺寸。對於接口,我正在使用Leaflet.js,Mapbox.js和jQuery。我接觸打印的方式是設置一個預覽窗口,僅在帶有白色背景的全新L.Map上顯示疊加層(無tileLayer),並且標記與用戶選擇的紙張大小成比例。這個想法是,地圖將填充頁面,並且標記始終以相同的尺寸打印(圓圈標記爲8毫米,圖標爲10毫米)。這裏的預覽窗口在Firefox中的截圖:單張張貼地圖以填充頁面

print preview window

有複雜的代碼公平一點。只要用戶改變窗口大小或紙張方向,就可以說預覽框和圖標相應地調整大小。每當用戶更改紙張大小時,圖標大小會調整,但預覽框不會顯示,以便表示正確的大小比率。下面是我用做它的職能:

function adjustPreviewBox(){ 
    //set preview box dimensions based on print window size and paper orientation 
    if ($("#paperOrientation option[value=portrait]").prop("selected")){ 
     var height = $("#printBox").height() - 61; 
     var width = height/Math.sqrt(2); 
     $("#printPreview").height(height); 
     $("#printPreview").width(width); 
    } else { 
     //first set by horizontal dimension 
     var width = $("#printBox").width() - 300; 
     var height = width/Math.sqrt(2); 
     //check for vertical overflow 
     if (height > $("#printBox").height() - 61){ 
      height = $("#printBox").height() - 61; 
      width = height * Math.sqrt(2); 
     }; 
     $("#printPreview").height(height); 
     $("#printPreview").width(width); 
    } 
}; 

function adjustScale(){ 
    //change symbol sizes and ratio scale according to paper size 
    var prevWidth = $("#printPreview").width(); 
    var prevHeight = $("#printPreview").height(); 
    var size = $("#paperSize select option:selected").val(); 
    var series = size[0]; 
    var pScale = Number(size[1]); 
    var longside, mmppPaper; 
    if (series == "A"){ //equations for long side lengths in mm, minus 10mm print margins 
     longside = Math.floor(1000/(Math.pow(2,(2*pScale-1)/4)) + 0.2) - 20; 
    } else if (series == "B"){ 
     longside = Math.floor(1000/(Math.pow(2,(pScale-1)/2)) + 0.2) - 20; 
    }; 
    //find the mm per pixel ratio 
    mmppPaper = prevWidth > prevHeight ? longside/prevWidth : longside/prevHeight; 
    var mapZoom = printPreviewMap.getZoom(); 
    var scaleText = $("#printBox .leaflet-control-scale-line").html().split(" "); 
    var multiplier = scaleText[1] == "km" ? 1000000 : 1000; 
    var scalemm = Number(scaleText[0]) * multiplier; 
    var scalepx = Number($("#printBox .leaflet-control-scale-line").width()); 
    var mmppMap = scalemm/scalepx; 
    var denominator = Math.round(mmppMap/mmppPaper); 
    $("#ratioScale span").text(denominator); 
    return [mmppMap, mmppPaper]; 
} 

function resizeMarkers(markerType, init){ 
    //scale preview marker size based on paper size and orientation 
    markerType == "circle" ? changeRadius(init) : changeIconSize(init); 
}; 

function getRadius(){ 
    //adjust ratio scale and return scale ratios 
    var scales = adjustScale(); 
    var mmppPaper = scales[1]; 
    return 4/mmppPaper; 
}; 

function changeRadius(init){ 
    //each circle marker will print at 8 mm diameter regardless of map scale and page size 
    var radius = getRadius(); 
    printPreviewMap.eachLayer(function(layer){ 
     if (typeof layer._radius !== 'undefined'){ 
      if (init == true){ 
       layer.setStyle({ 
        opacity: 1, 
        fillOpacity: 1 
       }); 
       layer.unbindPopup(); 
      }; 
      layer.setRadius(radius); 
     } 
    }); 
}; 

function changeIconSize(init){ 
    //each icon will print at 10 mm per side regardless of map scale and page size 
    var side = 2.5 * getRadius(); 

    //need to change dimensions and offset 
    $("#printPreview .leaflet-marker-icon").css({ 
     width: side + "px", 
     height: side + "px", 
     "margin-left": -(side/2), 
     "margin-top": -(side/2) 
    }) 
}; 

@media print CSS樣式,似乎也爲打印預覽窗口的工作:

@media print { 
    @page { 
     size: auto; 
     margin: 10mm; 
    } 

    #printBox, #printPreview { 
     position: absolute; 
     max-height: 100%; 
     bottom: 0; 
     left: 0; 
     top: 0; 
     right: 0; 
    } 

    #printPreview { 
     position: absolute !important; 
     width: 100% !important; 
     height: 100% !important; 
     border: none; 
    } 

    #scalegrip { 
     visibility: hidden; 
    } 

    #container { 
     visibility: hidden; 
    } 
} 

我已經通過打印到這個測試使用Adobe的驅動程序的PDF。這裏的結果:

PDF print of map

這似乎很好地工作 - 除了標記僅填充頁面的左上部分,而我想他們向外膨脹以填滿整個頁面,這樣最終產品與預覽框相同的「視圖」。這是我陷入困境的地方,並歡迎任何嘗試類似或知道打印網站方式的人的任何建議或想法。

回答

1

在類似的項目中,我必須在通過invalidateSize方法更改任何CSS大小後強制映射刷新。例如使用jQuery改變地圖的身高和體重的div:

$("map").css('width', '267mm'); 
$("map").css('height', '210mm'); 
map.invalidateSize(); 

根據leaflet help

invalidateSize:檢查地圖容器的尺寸改變和更新地圖如果是這樣 - 稱它爲後你」動態地改變了地圖大小,默認情況下也動畫平移。