我有一些有趣的CSS/JavaScript問題。我正在構建一個用戶友好的網絡地圖,其中包括自願提供的地理信息,並需要能夠以多種紙張尺寸打印,最多可以張貼海報尺寸。對於接口,我正在使用Leaflet.js,Mapbox.js和jQuery。我接觸打印的方式是設置一個預覽窗口,僅在帶有白色背景的全新L.Map上顯示疊加層(無tileLayer),並且標記與用戶選擇的紙張大小成比例。這個想法是,地圖將填充頁面,並且標記始終以相同的尺寸打印(圓圈標記爲8毫米,圖標爲10毫米)。這裏的預覽窗口在Firefox中的截圖:單張張貼地圖以填充頁面
有複雜的代碼公平一點。只要用戶改變窗口大小或紙張方向,就可以說預覽框和圖標相應地調整大小。每當用戶更改紙張大小時,圖標大小會調整,但預覽框不會顯示,以便表示正確的大小比率。下面是我用做它的職能:
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。這裏的結果:
這似乎很好地工作 - 除了標記僅填充頁面的左上部分,而我想他們向外膨脹以填滿整個頁面,這樣最終產品與預覽框相同的「視圖」。這是我陷入困境的地方,並歡迎任何嘗試類似或知道打印網站方式的人的任何建議或想法。