pageFeature.js (3842B)
1 import L from 'leaflet'; 2 import './page-feature.css'; 3 4 const PageFeature = L.Marker.extend({ 5 initialize: function(centerLatLng, paperSize, scale, label) { 6 this.paperSize = paperSize; 7 this.scale = scale; 8 var icon = L.divIcon({className: "print-page-marker", html: label}); 9 L.Marker.prototype.initialize.call(this, centerLatLng, { 10 icon: icon, 11 draggable: true, 12 title: 'Left click to rotate, right click for menu' 13 } 14 ); 15 this.on('drag', this.updateView.bind(this, undefined)); 16 }, 17 18 onAdd: function(map) { 19 L.Marker.prototype.onAdd.call(this, map); 20 map.on('viewreset', () => this.updateView()); 21 this.rectangle = L.rectangle([[0, 0], [0, 0]], 22 {color: '#ff7800', weight: 2, opacity: 0.7, fillOpacity: 0.2} 23 ).addTo(map); 24 this.updateView(); 25 }, 26 27 onRemove: function(map) { 28 map.off('viewreset', this.updateView, this); 29 L.Marker.prototype.onRemove.call(this, map); 30 this.rectangle.removeFrom(map); 31 }, 32 33 getLatLngBounds: function() { 34 return this.latLngBounds; 35 }, 36 37 _getLatLngBounds: function() { 38 const centerLatLng = this.getLatLng(); 39 const centerMerc = L.Projection.SphericalMercator.project(centerLatLng); 40 const mercatorScale = 41 (Math.cos((centerLatLng.lat * Math.PI) / 180) * L.CRS.Earth.R) / L.Projection.SphericalMercator.R; 42 const mercatorPageSize = L.point(...this.paperSize).multiplyBy(this.scale / 10 / mercatorScale); 43 let sw = centerMerc.subtract(mercatorPageSize.divideBy(2)); 44 let ne = centerMerc.add(mercatorPageSize.divideBy(2)); 45 sw = L.Projection.SphericalMercator.unproject(sw); 46 ne = L.Projection.SphericalMercator.unproject(ne); 47 return L.latLngBounds([sw, ne]); 48 }, 49 50 _animateZoom: function(e) { 51 L.Marker.prototype._animateZoom.call(this, e); 52 this.updateView(e.zoom); 53 }, 54 55 updateView: function(newZoom) { 56 if (!this._map) { 57 return; 58 } 59 if (newZoom === undefined) { 60 newZoom = this._map.getZoom(); 61 } 62 var bounds = this.latLngBounds = this._getLatLngBounds(); 63 var pixel_sw = this._map.project(bounds.getSouthWest(), newZoom); 64 var pixel_ne = this._map.project(bounds.getNorthEast(), newZoom); 65 var pixel_center = this._map.project(this.getLatLng(), newZoom); 66 var st = this._icon.style; 67 var pixel_width = pixel_ne.x - pixel_sw.x; 68 var pixel_height = pixel_sw.y - pixel_ne.y; 69 st.width = `${pixel_width}px`; 70 st.height = `${pixel_height}px`; 71 st.marginLeft = `${pixel_sw.x - pixel_center.x}px`; 72 st.marginTop = `${pixel_ne.y - pixel_center.y}px`; 73 st.fontSize = `${Math.min(pixel_width, pixel_height, 500) / 2}px`; 74 st.lineHeight = `${pixel_height}px`; 75 this.rectangle.setBounds(bounds); 76 }, 77 78 setLabel: function(s) { 79 this._icon.innerHTML = s; 80 }, 81 82 getLabel: function() { 83 return this._icon.innerHTML; 84 }, 85 86 setSize: function(paperSize, scale) { 87 this.paperSize = paperSize; 88 this.scale = scale; 89 this.updateView(); 90 }, 91 92 getPrintSize: function() { 93 return L.point(...this.paperSize); 94 }, 95 96 rotate: function() { 97 this.paperSize = [this.paperSize[1], this.paperSize[0]]; 98 this.updateView(); 99 } 100 101 } 102 ); 103 104 export default PageFeature;