宣传单展开地图以填写打印页面

时间:2015-04-04 14:11:28

标签: javascript jquery css leaflet mapbox

我有一个有趣的CSS / JavaScript问题。我正在构建一个用户友好的网络地图,其中包括自愿提供的地理信息,并且需要能够以多种纸张尺寸打印,最大可达海报尺寸。对于接口,我正在使用Leaflet.js,Mapbox.js和jQuery。我接近打印的方法是设置一个预览窗口,该窗口仅在具有白色背景的全新L.Map上显示叠加(无tileLayer),其中标记与用户选择的纸张大小成比例缩放。我们的想法是地图将填充页面,标记将始终以相同的尺寸打印(圆形标记为8 mm,图标为10 mm)。这是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 个答案:

答案 0 :(得分:1)

在类似的项目中,我必须在通过invalidateSize方法更改任何CSS大小后强制刷新地图。例如,使用jQuery更改地图高度和权重div:

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

根据leaflet help

  

invalidateSize:检查地图容器大小是否已更改并更新地图(如果是) - 在动态更改地图大小后调用它,默认情况下也为动画设置动画。