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

nor*_*ana 5 javascript css jquery leaflet mapbox

我有一个有趣的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)
    })
};
Run Code Online (Sandbox Code Playgroud)

我有@media printCSS样式,似乎适用于打印预览窗口:

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经通过使用Adobe的驱动程序打印到PDF来测试了这一点.这是结果:

PDF打印地图

它似乎工作正常 - 除了标记只填充页面的左上部分,而我希望它们向外扩展以填充整个页面,以便最终产品与预览框相同的"视图" .这是我很难过的地方,欢迎那些尝试类似或知道自己打印网站的人的任何建议或想法.

小智 2

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

\n\n
$("map").css(\'width\', \'267mm\');\n$("map").css(\'height\', \'210mm\');\nmap.invalidateSize();\n
Run Code Online (Sandbox Code Playgroud)\n\n

根据传单帮助

\n\n
\n

invalidateSize:检查地图容器大小是否更改并更新地图(如果是这样)\xe2\x80\x94 在动态更改地图大小后调用它,默认情况下也会对平移进行动画处理。

\n
\n