You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. var L = require('leaflet')
  2. require('./layout.css')
  3. require('./range.css')
  4. var mapWasDragEnabled
  5. // Leaflet v0.7 backwards compatibility
  6. function on (el, types, fn, context) {
  7. types.split(' ').forEach(function (type) {
  8. L.DomEvent.on(el, type, fn, context)
  9. })
  10. }
  11. // Leaflet v0.7 backwards compatibility
  12. function off (el, types, fn, context) {
  13. types.split(' ').forEach(function (type) {
  14. L.DomEvent.off(el, type, fn, context)
  15. })
  16. }
  17. function getRangeEvent (rangeInput) {
  18. return 'oninput' in rangeInput ? 'input' : 'change'
  19. }
  20. function cancelMapDrag () {
  21. mapWasDragEnabled = this._map.dragging.enabled()
  22. this._map.dragging.disable()
  23. }
  24. function uncancelMapDrag (e) {
  25. if (!mapWasDragEnabled) return
  26. this._refocusOnMap(e)
  27. this._map.dragging.enable()
  28. }
  29. // convert arg to an array - returns empty array if arg is undefined
  30. function asArray(arg) {
  31. return (arg === 'undefined') ? [] : Array.isArray(arg) ? arg : [arg]
  32. }
  33. function noop () {
  34. return
  35. }
  36. L.Control.SideBySide = L.Control.extend({
  37. options: {
  38. thumbSize: 42,
  39. padding: 0
  40. },
  41. initialize: function (leftLayers, rightLayers, options) {
  42. this.setLeftLayers(leftLayers)
  43. this.setRightLayers(rightLayers)
  44. L.setOptions(this, options)
  45. },
  46. getPosition: noop,
  47. setPosition: noop,
  48. includes: L.Mixin.Events,
  49. addTo: function (map) {
  50. this.remove()
  51. this._map = map
  52. var container = this._container = L.DomUtil.create('div', 'leaflet-sbs', map._controlContainer)
  53. this._divider = L.DomUtil.create('div', 'leaflet-sbs-divider', container)
  54. var range = this._range = L.DomUtil.create('input', 'leaflet-sbs-range', container)
  55. range.type = 'range'
  56. range.min = 0
  57. range.max = 1
  58. range.step = 'any'
  59. range.value = 0.5
  60. range.style.paddingLeft = range.style.paddingRight = this.options.padding + 'px'
  61. this._addEvents()
  62. this._updateLayers()
  63. return this
  64. },
  65. remove: function () {
  66. if (!this._map) {
  67. return this
  68. }
  69. this._removeEvents()
  70. L.DomUtil.remove(this._container)
  71. this._map = null
  72. return this
  73. },
  74. setLeftLayers: function (leftLayers) {
  75. this._leftLayers = asArray(leftLayers)
  76. this._updateLayers()
  77. return this
  78. },
  79. setRightLayers: function (rightLayers) {
  80. this._rightLayers = asArray(rightLayers)
  81. this._updateLayers()
  82. return this
  83. },
  84. _updateClip: function () {
  85. var map = this._map
  86. var rangeValue = this._range.value
  87. var nw = map.containerPointToLayerPoint([0, 0])
  88. var se = map.containerPointToLayerPoint(map.getSize())
  89. var offset = (0.5 - rangeValue) * (2 * this.options.padding + this.options.thumbSize)
  90. var clipX = nw.x + (se.x - nw.x) * rangeValue + offset
  91. var dividerX = map.getSize().x * rangeValue + offset
  92. this._divider.style.left = dividerX + 'px'
  93. this.fire('dividermove', {x: dividerX})
  94. var clipLeft = 'rect(' + [nw.y, clipX, se.y, nw.x].join('px,') + 'px)'
  95. var clipRight = 'rect(' + [nw.y, se.x, se.y, clipX].join('px,') + 'px)'
  96. if (this._leftLayer) {
  97. this._leftLayer.getContainer().style.clip = clipLeft
  98. }
  99. if (this._rightLayer) {
  100. this._rightLayer.getContainer().style.clip = clipRight
  101. }
  102. },
  103. _updateLayers: function () {
  104. var prevLeft = this._leftLayer
  105. var prevRight = this._rightLayer
  106. this._leftLayer = this._rightLayer = null
  107. this._leftLayers.forEach(function (layer) {
  108. if (this._map.hasLayer(layer)) {
  109. this._leftLayer = layer
  110. }
  111. }, this)
  112. this._rightLayers.forEach(function (layer) {
  113. if (this._map.hasLayer(layer)) {
  114. this._rightLayer = layer
  115. }
  116. }, this)
  117. if (prevLeft !== this._leftLayer) {
  118. prevLeft && this.fire('leftlayerremove', {layer: prevLeft})
  119. this._leftLayer && this.fire('leftlayeradd', {layer: this._leftLayer})
  120. }
  121. if (prevRight !== this._rightLayer) {
  122. prevRight && this.fire('rightlayerremove', {layer: prevRight})
  123. this._rightLayer && this.fire('rightlayeradd', {layer: this._rightLayer})
  124. }
  125. this._updateClip()
  126. },
  127. _addEvents: function () {
  128. var range = this._range
  129. var map = this._map
  130. if (!map || !range) return
  131. map.on('move', this._updateClip, this)
  132. map.on('layeradd layerremove', this._updateLayers, this)
  133. on(range, getRangeEvent(range), this._updateClip, this)
  134. on(range, 'mousedown touchstart', cancelMapDrag, this)
  135. on(range, 'mouseup touchend', uncancelMapDrag, this)
  136. },
  137. _removeEvents: function () {
  138. var range = this._range
  139. var map = this._map
  140. if (range) {
  141. off(range, getRangeEvent(range), this._updateClip, this)
  142. off(range, 'mousedown touchstart', cancelMapDrag, this)
  143. off(range, 'mouseup touchend', uncancelMapDrag, this)
  144. }
  145. if (map) {
  146. map.off('layeradd layerremove', this._updateLayers, this)
  147. map.off('move', this._updateClip, this)
  148. }
  149. }
  150. })
  151. L.control.sideBySide = function (leftLayers, rightLayers, options) {
  152. return new L.Control.SideBySide(leftLayers, rightLayers, options)
  153. }
  154. module.exports = L.Control.SideBySide