1L.Control.OpacitySlider = L.Control.extend({ 2 3 includes: L.Evented ? L.Evented.prototype : L.Mixin.Events, 4 5 options: { 6 position: 'topright', 7 opacity: 100, 8 backgroundColor: 'transparent', 9 sliderImageUrl: 'images/opacity-slider3d14.png', 10 margin: 5, 11 }, 12 13 _OPACITY_MAX_PIXELS: 69, 14 15 initialize: function(layer, options) { 16 L.Util.setOptions(this, options); 17 18 this.layer = layer; 19 this.layers = this.layer ? [this.layer] : []; 20 }, 21 22 onAdd: function(map) { 23 24 var container = this._container = L.DomUtil.create('DIV', 'opacity-control'); 25 var slider = this._slider = L.DomUtil.create('DIV', 'opacity-slider'); 26 var knob = this._knob = L.DomUtil.create('DIV', 'opacity-knob'); 27 28 container.setAttribute("style", "cursor:pointer;"); 29 slider.setAttribute("style", "margin:" + this.options.margin + "px;overflow-x:hidden;overflow-y:hidden;background:url(" + this.options.sliderImageUrl + ") no-repeat;width:71px;height:21px;"); 30 knob.setAttribute("style", "padding:0;margin:0;overflow-x:hidden;overflow-y:hidden;background:url(" + this.options.sliderImageUrl + ") no-repeat -71px 0;width:14px;height:21px;"); 31 32 slider.appendChild(knob); 33 container.appendChild(slider); 34 35 this.knob = new this.DraggableObject(knob, { 36 restrictY: true, 37 container: container, 38 onDragEnd: function(e) { 39 var opacity = this.knob.getValueX(); 40 this.setOpacity(opacity); 41 }.bind(this) 42 }); 43 44 L.DomEvent.on(container, 'click mousedown mousemove mouseup', function(e) { 45 L.DomUtil.disableTextSelection(); 46 if (e.type == 'mousedown') this._dragging = true; 47 else if (e.type == 'mouseup' || e.type == 'click') this._dragging = false; 48 49 if (e.type == 'mousemove' && this._dragging == true || e.type == 'click') { 50 var left = this.findPosLeft(this._container); 51 var x = e.pageX - left - this.options.margin; 52 this.knob.setValueX(x); 53 this.setOpacity(x); 54 } 55 }, this); 56 57 L.DomEvent.disableClickPropagation(container); 58 59 this._resetSlider(); 60 61 this.on('hidden', function(e) { 62 for (var i in this.layers) { 63 if (this.layers[i]) 64 this.layers[i].remove(); 65 } 66 }, this); 67 this.on('visible', function(e) { 68 for (var i in this.layers) { 69 if (this.layers[i]) 70 this.layers[i].addTo(this._map); 71 } 72 }, this); 73 74 if (!this.layer) { 75 if (map.options.layers && map.options.layers.length) { 76 this.setLayer(map.options.layers[0]); 77 this._setLayerOpacity(map.options.layers[0], this.opacity); 78 } 79 map.on('baselayerchange', function(e) { 80 this.setLayer(e.layer); 81 this._setLayerOpacity(e.layer, this.opacity); 82 }, this); 83 } 84 85 return container; 86 }, 87 88 setOpacity: function(pixelX) { 89 // Range = 0 to OPACITY_MAX_PIXELS 90 var value = (100 / this._OPACITY_MAX_PIXELS) * pixelX; 91 value = value / 100; 92 93 if (value < 0) { 94 value = 0; 95 } 96 97 this.fire(value > 0 ? 'visible' : 'hidden'); 98 99 if (this.layer) { 100 if (this.layer.eachLayer) { 101 this.layer.eachLayer(function(layer) { 102 this._setLayerOpacity(layer, value); 103 }, this); 104 } else { 105 this._setLayerOpacity(this.layer, value); 106 } 107 } 108 }, 109 110 _setLayerOpacity: function(layer, value) { 111 if (layer.setStyle) { 112 layer.setStyle({ 113 opacity: value 114 }); 115 this.opacity = value; 116 } else if (layer.setOpacity) { 117 layer.setOpacity(value); 118 this.opacity = value; 119 } 120 }, 121 122 findPosLeft: function(obj) { 123 var curleft = 0; 124 if (obj.offsetParent) { 125 do { 126 curleft += obj.offsetLeft; 127 obj = obj.offsetParent; 128 } while (obj); 129 return curleft; 130 } 131 return undefined; 132 }, 133 134 getLayer: function() { 135 return this.layer; 136 }, 137 138 setLayer: function(layer) { 139 this.removeFeatureLayer(this.layer); 140 this.addFeatureLayer(layer); 141 this.layer = layer; 142 }, 143 144 addFeatureLayer: function(layer) { 145 this.layers.push(layer); 146 return this.layers; 147 }, 148 149 removeFeatureLayer: function(layer) { 150 for (var i in this.layers) { 151 if (this.layers[i] && this.layers[i]._leaflet_id === layer._leaflet_id) { 152 this.layers.splice(i, 1); 153 } 154 } 155 return this.layers; 156 }, 157 158 _resetSlider: function() { 159 // Set initial value 160 this._initialValue = this._OPACITY_MAX_PIXELS / (100 / this.options.opacity); 161 this.knob.setValueX(this._initialValue); 162 this.setOpacity(this._initialValue); 163 }, 164 165 /** 166 * TODO: trying to replace with the "L.Draggable" class 167 */ 168 DraggableObject: function(src, options) { 169 var self = this; 170 171 var _opts = { 172 draggingCursor: "default", 173 draggableCursor: "default", 174 onDragStart: _dumbFunction, 175 onDragEnd: _dumbFunction, 176 onDragging: _dumbFunction, 177 onMouseDown: _dumbFunction, 178 onMouseUp: _dumbFunction, 179 intervalX: 1, 180 intervalY: 1, 181 toleranceX: Infinity, 182 toleranceY: Infinity, 183 interval: 1 184 }; 185 186 L.Util.extend(_opts, options); 187 188 var _draggingCursor = _opts.draggingCursor; 189 var _draggableCursor = _opts.draggableCursor; 190 var _dragging = false;
191 var _preventDefault; 192 var _currentX, _currentY, _formerY, _formerX, _formerMouseX, _formerMouseY; 193 var _top, _left; 194 var _originalX, _originalY; 195 var _target = src.setCapture ? src : document; 196 197 _opts.left = _opts.left || src.offsetLeft; 198 _opts.top = _opts.top || src.offsetTop; 199 200 src.style.position = "absolute"; 201 202 src.addEventListener("mousedown", _mouseDown); 203 _target.addEventListener("mouseup", _mouseUp); 204 205 _setCursor(false); 206 _moveTo(_opts.left, _opts.top, false); 207 208 /** 209 * Set the cursor for {@link src} based on whether or not 210 * the element is currently being dragged. 211 * @param {Boolean} a Is the element being dragged? 212 * @private 213 */ 214 function _setCursor(a) { 215 src.style.cursor = a ? _draggingCursor : _draggableCursor; 216 } 217 218 /** 219 * Moves the element {@link src} to the given 220 * location. 221 * @param {Number} x The left position to move to. 222 * @param {Number} y The top position to move to. 223 * @param {Boolean} prevent Prevent moving? 224 * @private 225 */ 226 function _moveTo(x, y, prevent) { 227 _left = Math.round(x); 228 _top = Math.round(y); 229 230 if (_opts.intervalX > 1) { 231 var halfIntervalX = Math.round(_opts.intervalX / 2); 232 var roundedIntervalX = Math.round(_left % _opts.intervalX); 233 _left = (roundedIntervalX < halfIntervalX) ? (_left - roundedIntervalX) : (_left + (_opts.intervalX - roundedIntervalX)); 234 } 235 if (_opts.intervalY > 1) { 236 var halfIntervalY = Math.round(_opts.intervalY / 2); 237 var roundedIntervalY = Math.round(_top % _opts.intervalY); 238 _top = (roundedIntervalY < halfIntervalY) ? (_top - roundedIntervalY) : (_top + (_opts.intervalY - roundedIntervalY)); 239 } 240 if (_opts.container && _opts.container.offsetWidth) { 241 _left = Math.max(0, Math.min(_left, _opts.container.offsetWidth - src.offsetWidth)); 242 _top = Math.max(0, Math.min(_top, _opts.container.offsetHeight - src.offsetHeight)); 243 } 244 if (typeof _currentX === "number") { 245 if (((_left - _currentX) > _opts.toleranceX || (_currentX - (_left + src.offsetWidth)) > _opts.toleranceX) || ((_top - _currentY) > _opts.toleranceY || (_currentY - (_top + src.offsetHeight)) > _opts.toleranceY)) { 246 _left = _originalX; 247 _top = _originalY; 248 } 249 } 250 src.style.left = !_opts.restrictX && !prevent ? _left + "px" : src.style.left; 251 src.style.top = !_opts.restrictY && !prevent ? _top + "px" : src.style.top; 252 } 253 254 /** 255 * Handles the mousemove event. 256 * @param {event} ev The event data sent by the browser. 257 * @private 258 */ 259 function _mouseMove(ev) { 260 var e = ev || event; 261 _currentX = _formerX + ((_getFormerMouseX(e)) - _formerMouseX); 262 _currentY = _formerY + ((_getFormerMouseY(e)) - _formerMouseY); 263 _formerX = _currentX; 264 _formerY = _currentY; 265 _formerMouseX = _getFormerMouseX(e); 266 _formerMouseY = _getFormerMouseY(e); 267 if (_dragging) { 268 _moveTo(_currentX, _currentY, _preventDefault); 269 _opts.onDragging({ 270 mouseX: _formerMouseX, 271 mouseY: _formerMouseY, 272 startLeft: _originalX, 273 startTop: _originalY, 274 event: e 275 }); 276 } 277 } 278 279 /** 280 * Handles the mousedown event. 281 * @param {event} ev The event data sent by the browser. 282 * @private 283 */ 284 function _mouseDown(ev) { 285 var e = ev || event; 286 _setCursor(true); 287 _opts.onMouseDown(e); 288 if (src.style.position !== "absolute") { 289 src.style.position = "absolute"; 290 return; 291 } 292 _formerMouseX = _getFormerMouseX(e); 293 _formerMouseY = _getFormerMouseY(e); 294 _originalX = src.offsetLeft; 295 _originalY = src.offsetTop; 296 _formerX = _originalX; 297 _formerY = _originalY; 298 _target.addEventListener("mousemove", _mouseMove); 299 if (src.setCapture) { 300 src.setCapture(); 301 } 302 if (e.preventDefault) { 303 e.preventDefault(); 304 e.stopPropagation(); 305 } else { 306 e.cancelBubble = true; 307 e.returnValue = false;
308 } 309 _dragging = true; 310 _opts.onDragStart({ 311 mouseX: _formerMouseX, 312 mouseY: _formerMouseY, 313 startLeft: _originalX, 314 startTop: _originalY, 315 event: e 316 }); 317 } 318 319 /** 320 * Handles the mouseup event. 321 * @param {event} ev The event data sent by the browser. 322 * @private 323 */ 324 function _mouseUp(ev) { 325 var e = ev || event; 326 if (_dragging) { 327 _setCursor(false); 328 _target.removeEventListener("mousemove", _mouseMove); 329 if (src.releaseCapture) { 330 src.releaseCapture(); 331 } 332 _dragging = false; 333 _opts.onDragEnd({ 334 mouseX: _formerMouseX, 335 mouseY: _formerMouseY, 336 startLeft: _originalX, 337 startTop: _originalY, 338 event: e 339 }); 340 } 341 _currentX = _currentY = null; 342 _opts.onMouseUp(e); 343 } 344 345 function _getFormerMouseX(e) { 346 return e.pageX || (e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft); 347 } 348 349 function _getFormerMouseY(e) { 350 return e.pageY || (e.clientY + document.body.scrollTop + document.documentElement.scrollTop); 351 } 352 353 function _dumbFunction(e) {} 354 355 /** 356 * Move the element {@link src} to the given location. 357 * @param {Point} point An object with an x and y property 358 * that represents the location to move to. 359 */ 360 self.moveTo = function(point) { 361 _moveTo(point.x, point.y, false); 362 }; 363 364 /** 365 * Move the element {@link src} by the given amount. 366 * @param {Size} size An object with an x and y property 367 * that represents distance to move the element. 368 */ 369 self.moveBy = function(size) { 370 _moveTo(src.offsetLeft + size.width, src.offsetHeight + size.height, false); 371 }; 372 373 /** 374 * Sets the cursor for the dragging state. 375 * @param {String} cursor The name of the cursor to use. 376 */ 377 self.setDraggingCursor = function(cursor) { 378 _draggingCursor = cursor; 379 _setCursor(_dragging); 380 }; 381 382 /** 383 * Sets the cursor for the draggable state. 384 * @param {String} cursor The name of the cursor to use. 385 */ 386 self.setDraggableCursor = function(cursor) { 387 _draggableCursor = cursor; 388 _setCursor(_dragging); 389 }; 390 391 /** 392 * Returns the current left location. 393 * @return {Number} 394 */ 395 self.left = function() { 396 return _left; 397 }; 398 399 /** 400 * Returns the current top location. 401 * @return {Number} 402 */ 403 self.top = function() { 404 return _top; 405 }; 406 407 /** 408 * Returns the number of intervals the element has moved 409 * along the X axis. Useful for scrollbar type 410 * applications. 411 * @return {Number} 412 */ 413 self.getValueX = function() { 414 var i = _opts.intervalX || 1; 415 return Math.round(_left / i); 416 }; 417 418 /** 419 * Returns the number of intervals the element has moved 420 * along the Y axis. Useful for scrollbar type 421 * applications. 422 * @return {Number} 423 */ 424 self.getValueY = function() { 425 var i = _opts.intervalY || 1; 426 return Math.round(_top / i); 427 }; 428 429 /** 430 * Sets the left position of the draggable object based on 431 * intervalX. 432 * @param {Number} value The location to move to. 433 */ 434 self.setValueX = function(value) { 435 _moveTo(value * _opts.intervalX, _top, false); 436 }; 437 438 /** 439 * Sets the top position of the draggable object based on 440 * intervalY. 441 * @param {Number} value The location to move to. 442 */ 443 self.setValueY = function(value) { 444 _moveTo(_left, value * _opts.intervalY, false); 445 }; 446 447 /** 448 * Prevents the default movement behavior of the object. 449 * The object can still be moved by other methods. 450 */ 451 self.preventDefaultMovement = function(prevent) { 452 _preventDefault = prevent; 453 }; 454 } 455 /** 456 * @name DraggableObjectOptions 457 * @class This class represents the optional parameter passed into constructor of 458 * <code>DraggableObject</code>. 459 * @property {Number} [top] Top pixel 460 * @property {Number} [left] Left pixel 461 * @property {HTMLElement} [container] HTMLElement as container. 462 * @property {String} [draggingCursor] Dragging Cursor 463 * @property {String} [draggableCursor] Draggable Cursor 464 * @property {Number} [intervalX] Interval in X direction 465 * @property {Number} [intervalY] Interval in Y direction 466 * @property {Number} [toleranceX] Tolerance X in pixel 467 * @property {Number} [toleranceY] Tolerance Y in pixel 468 * @property {Boolean} [restrictX] Whether to restrict move in X direction 469 * @property {Boolean} [restrictY] Whether to restrict move in Y direction 470 */ 471});
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.