2015-04-04 21 views
5

İlginç CSS/JavaScript sorununuza sahiptir. Gönüllü coğrafi bilgileri içerecek ve poster boyutuna kadar çok sayıda kağıt boyutunda baskı yapma olanağına sahip kullanıcı dostu bir web haritası hazırlıyorum. Arabirim için Leaflet.js, Mapbox.js ve jQuery ile çalışıyorum. Yazdırmaya yaklaştığım yol, tamamen beyaz bir arka plana sahip tamamen yeni bir L.Map üzerinde (hiçbir tileLayer yok) katmanları gösteren bir önizleme penceresi oluşturmaktır; işaretçiler, kullanıcı tarafından seçilen kağıt boyutuna orantılı olarak ölçeklenir. Buradaki fikir, haritanın sayfayı dolduracağı ve işaretleyicilerin her zaman aynı boyutta (daire işaretleri için 8 mm, simgeler için 10 mm) yazacağıdır. İşte Firefox önizleme penceresinin bir ekran görüntüsü:Leaflet, haritayı kopyalamak için sayfayı genişlet

print preview window

karmaşık kod adil biraz vardır. Kullanıcı pencere boyutunu veya kağıt yönünü her değiştirdiğinde, önizleme kutusu ve simgelerin buna göre yeniden boyutlandığını söylemek için yeterli olur. Kullanıcı kağıt boyutunu değiştirdiğinde, doğru boyut oranlarını temsil edecek şekilde simgeler yeniden boyutlandırılır ancak önizleme kutusu kullanılmaz.

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) 
    }) 
}; 

Ben önizleme penceresini yazdırmak için iyi çalışmıyor gibi görünüyor @media print CSS stilleri var: Ben yazdırarak test ettik

@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; 
    } 
} 

İşte bunu yapmak için kullanıyorum fonksiyonlardır Adobe'nin sürücüsünü kullanan bir PDF. İşte sonuç var:

PDF print of map

çok iyi çalışıyor görünüyor

- işaretler yalnızca sayfanın sol üst kısmını doldurmak dışında, onları istiyorum oysa dışa genişletmek için böylece sayfanın tamamını dolduracak şekilde son ürün önizleme kutusuyla aynı 'görünüm'. Bu, güvendiğim yerdir ve benzer bir şeyi deneyen veya web sitelerini yazdırma yollarını bilen herkesin tavsiyelerini veya fikirlerini memnuniyetle karşılayacaktır.

cevap

1

Benzer bir projede, herhangi bir CSS boyutu invalidateSize yöntemiyle değiştirildikten sonra haritayı yenilemek zorunda bıraktım.

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

göre leaflet help için:

invalidateSize: Harita yüksekliği ve ağırlığı div değiştirmek için jQuery kullanarak Örneğin haritası konteyner boyutu değişti ve eğer öyleyse haritayı güncelleyen eğer Çek - 'senden sonra diyoruz ve harita boyutunu dinamik olarak değiştirdi, ayrıca varsayılan olarak tavada animasyon.

İlgili konular