Ich habe in interessanten CSS/JavaScript-Problem. Ich erstelle eine benutzerfreundliche Webkarte mit freiwilligen geographischen Informationen und muss in der Lage sein, in mehreren Papierformaten bis zur Größe des Posters zu drucken. Für die Schnittstelle arbeite ich mit Leaflet.js, Mapbox.js und jQuery. Die Art, wie ich mich dem Druckvorgang genähert habe, besteht darin, ein Vorschaufenster einzurichten, das nur Overlays (kein tileLayer) auf einer völlig neuen L.Map mit weißem Hintergrund zeigt, wobei die Marker proportional zu der vom Benutzer gewählten Papiergröße skaliert werden. Die Idee ist, dass die Karte die Seite füllt und die Marker immer in der gleichen Größe drucken (8 mm Durchmesser für Kreismarkierungen, 10 mm für Symbole). Hier ist ein Screenshot des Vorschaufensters in Firefox:Prospekt erweitern Karte zu Seite füllen auf
Es gibt ein gutes Stück von komplexem Code ist. Es genügt zu sagen, dass, wenn der Benutzer die Fenstergröße oder die Papierausrichtung ändert, die Vorschaubox und die Symbole entsprechend angepasst werden. Wenn der Benutzer die Papiergröße ändert, ändert sich die Größe der Symbole, aber die Vorschau-Box nicht, um die richtigen Größenverhältnisse darzustellen. Hier sind die Funktionen verwende ich es zu tun:
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)
})
};
Ich habe @media print
CSS-Stile, die gut zu funktionieren scheint für das Drucken der Vorschaufenster:
@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;
}
}
ich getestet habe dies durch Drucken auf eine PDF mit Adobe-Treiber. Hier ist das Ergebnis:
Es scheint gut zu funktionieren - außer, dass die Markierungen nur den linken oberen Teil der Seite füllen, während ich sie möchte nach außen zu erweitern, um die gesamten Seite zu füllen, so dass Das Endprodukt ist dieselbe "Ansicht" wie die Vorschau-Box. Dies ist, wo ich ratlos bin und würde jeden Rat oder Ideen von jedem begrüßen, der etwas Ähnliches versucht hat oder sich in Druckerei-Websites auskennt.