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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. initialize: function (leftLayers, rightLayers) {
  38. this.setLeftLayers(leftLayers)
  39. this.setRightLayers(rightLayers)
  40. },
  41. getPosition: noop,
  42. setPosition: noop,
  43. includes: L.Mixin.Events,
  44. addTo: function (map) {
  45. this.remove()
  46. this._map = map
  47. var container = this._container = L.DomUtil.create('div', 'leaflet-sbs', map._controlContainer)
  48. this._divider = L.DomUtil.create('div', 'leaflet-sbs-divider', container)
  49. var range = this._range = L.DomUtil.create('input', 'leaflet-sbs-range', container)
  50. range.type = 'range'
  51. range.min = 0
  52. range.max = 1
  53. range.step = 'any'
  54. range.value = 0.5
  55. this._addEvents()
  56. this._updateLayers()
  57. return this
  58. },
  59. remove: function () {
  60. if (!this._map) {
  61. return this
  62. }
  63. this._removeEvents()
  64. L.DomUtil.remove(this._container)
  65. this._map = null
  66. return this
  67. },
  68. setLeftLayers: function (leftLayers) {
  69. this._leftLayers = asArray(leftLayers)
  70. this._updateLayers()
  71. return this
  72. },
  73. setRightLayers: function (rightLayers) {
  74. this._rightLayers = asArray(rightLayers)
  75. this._updateLayers()
  76. return this
  77. },
  78. _updateClip: function () {
  79. var map = this._map
  80. var rangeValue = this._range.value
  81. var nw = map.containerPointToLayerPoint([0, 0])
  82. var se = map.containerPointToLayerPoint(map.getSize())
  83. var offset = (0.5 - rangeValue) * 44
  84. var clipX = nw.x + (se.x - nw.x) * rangeValue + offset
  85. var dividerX = map.getSize().x * rangeValue + offset
  86. this._divider.style.left = dividerX + 'px'
  87. this.fire('dividermove', {x: dividerX})
  88. var clipLeft = 'rect(' + [nw.y, clipX, se.y, nw.x].join('px,') + 'px)'
  89. var clipRight = 'rect(' + [nw.y, se.x, se.y, clipX].join('px,') + 'px)'
  90. if (this._leftLayer) {
  91. this._leftLayer.getContainer().style.clip = clipLeft
  92. }
  93. if (this._rightLayer) {
  94. this._rightLayer.getContainer().style.clip = clipRight
  95. }
  96. },
  97. _updateLayers: function () {
  98. var prevLeft = this._leftLayer
  99. var prevRight = this._rightLayer
  100. this._leftLayer = this._rightLayer = null
  101. this._leftLayers.forEach(function (layer) {
  102. if (this._map.hasLayer(layer)) {
  103. this._leftLayer = layer
  104. }
  105. }, this)
  106. this._rightLayers.forEach(function (layer) {
  107. if (this._map.hasLayer(layer)) {
  108. this._rightLayer = layer
  109. }
  110. }, this)
  111. if (prevLeft !== this._leftLayer) {
  112. prevLeft && this.fire('leftlayerremove', {layer: prevLeft})
  113. this._leftLayer && this.fire('leftlayeradd', {layer: this._leftLayer})
  114. }
  115. if (prevRight !== this._rightLayer) {
  116. prevRight && this.fire('rightlayerremove', {layer: prevRight})
  117. this._rightLayer && this.fire('rightlayeradd', {layer: this._rightLayer})
  118. }
  119. this._updateClip()
  120. },
  121. _addEvents: function () {
  122. var range = this._range
  123. var map = this._map
  124. if (!map || !range) return
  125. map.on('move', this._updateClip, this)
  126. map.on('layeradd layerremove', this._updateLayers, this)
  127. on(range, getRangeEvent(range), this._updateClip, this)
  128. on(range, 'mousedown touchstart', cancelMapDrag, this)
  129. on(range, 'mouseup touchend', uncancelMapDrag, this)
  130. },
  131. _removeEvents: function () {
  132. var range = this._range
  133. var map = this._map
  134. if (range) {
  135. off(range, getRangeEvent(range), this._updateClip, this)
  136. off(range, 'mousedown touchstart', cancelMapDrag, this)
  137. off(range, 'mouseup touchend', uncancelMapDrag, this)
  138. }
  139. if (map) {
  140. map.off('layeradd layerremove', this._updateLayers, this)
  141. map.off('move', this._updateClip, this)
  142. }
  143. }
  144. })
  145. L.control.sideBySide = function (leftLayers, rightLayers, options) {
  146. return new L.Control.SideBySide(leftLayers, rightLayers, options)
  147. }
  148. module.exports = L.Control.SideBySide