1/** 2 * @namespace WPGMZA 3 * @module OLTextOverlay 4 * @requires WPGMZA.OLText 5 */ 6jQuery(function($) { 7 8 WPGMZA.OLTextOverlay = function(options){ 9 if(!options.position || !options.map) { 10 return; 11 } 12 13 this.element = $("<div class='wpgmza-ol-text-overlay-wrapper" + (options.class ? ` ${options.class}` : '') + "'></div>")[0]; 14 15 this.styleOptions = (!options) ? {} : options; 16 this.map = options.map; 17 18 this.offsetX = parseFloat(options.offsetX) || 0; 19 this.offsetY = parseFloat(options.offsetY) || 0; 20 21 /* "top-left" pins the element's own top-left corner at the projected pixel with no 22 * measurement of any kind on OL's part - centering AND the user-configurable offset 23 * are both applied ourselves as a single CSS transform on this.element (see 24 * setOffset()), exactly like GoogleTextOverlay does on .wpgmza-inner. OL's own 25 * "center-center" positioning was tried first, but unlike Leaflet/Google (which 26 * center via a self-referential CSS percentage transform, unaffected by content 27 * size or timing) OL centers via a JS-measured pixel margin - which didn't track 28 * correctly here. Doing it ourselves in pure CSS sidesteps that entirely. */ 29 this.olOverlay = new ol.Overlay({ 30 element : this.element, 31 position : ol.proj.fromLonLat([options.position.lng, options.position.lat]), 32 positioning : "top-left", 33 stopEvent : false 34 }); 35 36 this.applyTransform(); 37 38 this.map.olMap.addOverlay(this.olOverlay); 39 40 this.refresh(); 41 } 42 43 WPGMZA.OLTextOverlay.prototype.getStyle = function(){ 44 let defaults = { 45 fontSize : 11, 46 fillColor : "#000000", 47 strokeColor : "#ffffff" 48 }; 49 50 for(let i in defaults){ 51 if(typeof this.styleOptions[i] === 'undefined'){ 52 this.styleOptions[i] = defaults[i] 53 } 54 } 55 56 let labelStyles = []; 57 labelStyles.push("width: fit-content"); 58 labelStyles.push("font: bold " + this.styleOptions.fontSize + "px \"Open Sans\", \"Arial Unicode MS\", \"sans-serif\""); 59 labelStyles.push("color: " + this.styleOptions.fillColor); 60 labelStyles.push("z-index: 10"); 61 labelStyles.push("text-shadow: -1px -1px 0 " + this.styleOptions.strokeColor + ", 1px -1px 0 " + this.styleOptions.strokeColor + ", -1px 1px 0 " + this.styleOptions.strokeColor + ", 1px 1px 0 " + this.styleOptions.strokeColor); 62 63 if(this.styleOptions.opacity){ 64 labelStyles.push("opacity: " + this.styleOptions.opacity); 65 } 66 67 return labelStyles.join('; '); 68 } 69 70 WPGMZA.OLTextOverlay.prototype.refresh = function(){ 71 if(!this.styleOptions){ return; } 72 this.setText(this.styleOptions.text); 73 } 74 75 /** 76 * Applies centering plus the user-configurable offset as ONE CSS transform on 77 * this.element itself - translate(-50%,-50%) centers the element on the point (a 78 * self-referential percentage, always correct regardless of the element's actual 79 * rendered size, with no measurement needed), composed with a further translate(X%,Y%) 80 * for the offset, which is a percentage of that same box - so "100%" always means 81 * "shifted by one full label width/height", however long the title/subheading gets. 82 * Not a pixel offset baked into a nudged lat/lng either - that only holds true at the 83 * zoom level it was computed at, and would drift away from whatever this label is 84 * meant to stay anchored next to (e.g. its owning marker) as soon as the map zoomed. 85 * 86 * @return void 87 */ 88 WPGMZA.OLTextOverlay.prototype.applyTransform = function(){ 89 if(this.element){ 90 $(this.element).css('transform', 'translate(-50%, -50%) translate(' + (this.offsetX || 0) + '%, ' + (this.offsetY || 0) + '%)'); 91 } 92 } 93 94 /** 95 * @param number x 96 * @param number y 97 * 98 * @return void 99 */ 100 WPGMZA.OLTextOverlay.prototype.setOffset = function(x, y){ 101 this.offsetX = parseFloat(x) || 0; 102 this.offsetY = parseFloat(y) || 0; 103 104 this.applyTransform(); 105 } 106 107 /** 108 * Stores the owning marker (only ever set for a marker-owned label, never a standalone 109 * Point Label) and (re)applies click-to-select behaviour, gated behind the 110 * marker_label_click_opens_infowindow map setting. Bound directly on this.element, 111 * which OL never recreates itself. pointer-events is overridden here too, since the 112 * wrapper is pointer-events:none by default (see open-layers.css) s
112o clicks reach the 113 * map underneath when this is off. 114 * 115 * A real marker click dispatches a "select" event on the WPGMZA.Marker instance itself 116 * (see WPGMZA.Marker.prototype.onSelect), which is what actually opens the info 117 * window, so this reuses that same path rather than reimplementing it. 118 * 119 * @param WPGMZA.Marker|undefined marker 120 * 121 * @return void 122 */ 123 WPGMZA.OLTextOverlay.prototype.setMarker = function(marker){ 124 this.marker = marker; 125 126 if(!this.element){ return; } 127 128 var self = this; 129 var clickable = !!(this.marker && this.marker.map && this.marker.map.settings && this.marker.map.settings.marker_label_click_opens_infowindow); 130 131 $(this.element).css('pointer-events', clickable ? 'auto' : ''); 132 $(this.element).off('click.wpgmzaLabelSelect'); 133 134 if(clickable){ 135 $(this.element).on('click.wpgmzaLabelSelect', function(event){ 136 event.stopPropagation(); 137 self.marker.dispatchEvent("select"); 138 }); 139 } 140 } 141 142 WPGMZA.OLTextOverlay.prototype.setPosition = function(position){ 143 if(this.olOverlay){ 144 this.olOverlay.setPosition(ol.proj.fromLonLat([ 145 parseFloat(position.lng), 146 parseFloat(position.lat) 147 ])); 148 } 149 } 150 151 WPGMZA.OLTextOverlay.prototype.setText = function(text){ 152 if(!this.styleOptions){ return; } 153 154 if(text){ 155 this.styleOptions.text = text; 156 } 157 158 if(this.element){ 159 $(this.element).html(`<div class='wpgmza-ol-text-overlay' style='${this.getStyle()}'>${this.styleOptions.text || ''}</div>`); 160 } 161 } 162 163 /** 164 * Builds the card element - title, optional subheading, optional icon. Colors/background/border/ 165 * font size come entirely from the --wpgmza-component-* CSS vars (see components.css), not 166 * fillColor/lineColor/fontSize - those fields are hidden in the editor for card style. Opacity 167 * still applies since that remains relevant either way 168 * 169 * @return jQuery 170 */ 171 WPGMZA.OLTextOverlay.prototype.getCardElement = function(){ 172 const content = this.cardContent || {}; 173 const card = $("<div class='wpgmza-text-overlay-card'></div>"); 174 175 if(typeof this.styleOptions.opacity !== 'undefined'){ 176 card.css('opacity', this.styleOptions.opacity); 177 } 178 179 if(content.icon){ 180 card.append($("<img class='wpgmza-text-overlay-card-icon'/>").attr('src', content.icon)); 181 } 182 183 const textWrapper = $("<div class='wpgmza-text-overlay-card-content'></div>"); 184 textWrapper.append($("<div class='wpgmza-text-overlay-card-title'></div>").text(content.title || '')); 185 186 if(content.subText){ 187 textWrapper.append($("<div class='wpgmza-text-overlay-card-subtext'></div>").text(content.subText)); 188 } 189 190 card.append(textWrapper); 191 192 return card; 193 } 194 195 WPGMZA.OLTextOverlay.prototype.setCardContent = function(content){ 196 if(!this.styleOptions){ return; } 197 198 this.cardContent = content || {}; 199 200 if(this.element){ 201 $(this.element).empty().append(this.getCardElement()); 202 } 203 } 204 205 WPGMZA.OLTextOverlay.prototype.setFontSize = function(size){ 206 if(!this.styleOptions){ return; } 207 208 size = parseInt(size); 209 this.styleOptions.fontSize = size; 210 } 211 212 WPGMZA.OLTextOverlay.prototype.setFillColor = function(color){ 213 if(!this.styleOptions){ return; } 214 215 if(!color.match(/^#/)) 216 color = "#" + color; 217 218 219 this.styleOptions.fillColor = color; 220 } 221 222 WPGMZA.OLTextOverlay.prototype.setLineColor = function(color){ 223 if(!this.styleOptions){ return; } 224 225 if(!color.match(/^#/)) 226 color = "#" + color; 227 228 this.styleOptions.strokeColor = color 229 } 230 231 WPGMZA.OLTextOverlay.prototype.setOpacity = function(opacity){ 232 if(!this.styleOptions){ return; } 233 234 opacity = parseFloat(opacity); 235 236 if(opacity > 1){ 237 opacity = 1; 238 } else if (opacity < 0){ 239 opacity = 0; 240 } 241 242 this.styleOptions.opacity = opacity; 243 } 244 245 WPGMZA.OLTextOverlay.prototype.setZIndex = function(zIndex){ 246 if(this.element){ 247 $(this.element).css('z-index', zIndex); 248 } 249 } 250 251 252 WPGMZA.OLTextOverlay.prototype.remove = function(){ 253 if(this.olOverlay && this.map && this.map.olMap){ 254 this.map.olMap.removeOverlay(this.olOverlay); 255 } 256 } 257 258});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.