我有一个有趣的CSS / JavaScript问题。我正在构建一个用户友好的网络地图,其中包括自愿提供的地理信息,并且需要能够以多种纸张尺寸打印,最大可达海报尺寸。对于接口,我正在使用Leaflet.js,Mapbox.js和jQuery。我接近打印的方法是设置一个预览窗口,该窗口仅在具有白色背景的全新L.Map上显示叠加(无tileLayer),其中标记与用户选择的纸张大小成比例缩放。我们的想法是地图将填充页面,标记将始终以相同的尺寸打印(圆形标记为8 mm,图标为10 mm)。这是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进行了测试。结果如下:
它似乎工作正常 - 除了标记只填充页面的左上部分,而我希望它们向外扩展以填充整个页面,以便最终产品与“视图”相同预览框。这是我很难过的地方,欢迎那些尝试类似或知道自己打印网站的人的任何建议或想法。
答案 0 :(得分:1)
在类似的项目中,我必须在通过invalidateSize方法更改任何CSS大小后强制刷新地图。例如,使用jQuery更改地图高度和权重div:
$("map").css('width', '267mm');
$("map").css('height', '210mm');
map.invalidateSize();
根据leaflet help:
invalidateSize:检查地图容器大小是否已更改并更新地图(如果是) - 在动态更改地图大小后调用它,默认情况下也为动画设置动画。