您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

DivIcon.js 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /**
  2. * @Author: Caven
  3. * @Date: 2020-02-12 21:46:22
  4. */
  5. import { Cesium } from '@dc-modules/namespace'
  6. import State from '@dc-modules/state/State'
  7. import Parse from '@dc-modules/parse/Parse'
  8. import { DomUtil, Util } from '@dc-modules/utils'
  9. import { MouseEventType } from '@dc-modules/event'
  10. import { isBetween } from '@dc-modules/math'
  11. import { Transform } from '@dc-modules/transform'
  12. import Overlay from '../Overlay'
  13. class DivIcon extends Overlay {
  14. constructor(position, content) {
  15. super()
  16. this._delegate = DomUtil.create('div', 'div-icon')
  17. this._position = Parse.parsePosition(position)
  18. this._delegate.setAttribute('id', this._id)
  19. Util.merge(this._delegate.style, {
  20. position: 'absolute',
  21. top: '0',
  22. left: '0'
  23. })
  24. this.content = content
  25. this.type = Overlay.getOverlayType('div_icon')
  26. this._state = State.INITIALIZED
  27. }
  28. set show(show) {
  29. this._show = show
  30. this._delegate.style.visibility = this._show ? 'visible' : 'hidden'
  31. return this
  32. }
  33. get show() {
  34. return this._show
  35. }
  36. set position(position) {
  37. this._position = Parse.parsePosition(position)
  38. return this
  39. }
  40. get position() {
  41. return this._position
  42. }
  43. set content(content) {
  44. if (content && typeof content === 'string') {
  45. this._delegate.innerHTML = content
  46. } else if (content && content instanceof Element) {
  47. while (this._delegate.hasChildNodes()) {
  48. this._delegate.removeChild(this._delegate.firstChild)
  49. }
  50. this._delegate.appendChild(content)
  51. }
  52. return this
  53. }
  54. get content() {
  55. return this._delegate.childNodes || []
  56. }
  57. /**
  58. * Updates style
  59. * @param style
  60. * @param distance
  61. * @private
  62. */
  63. _updateStyle(style, distance) {
  64. let translate3d = 'translate3d(0,0,0)'
  65. if (style.transform) {
  66. let x = style.transform.x - this._delegate.offsetWidth / 2
  67. let y = style.transform.y - this._delegate.offsetHeight / 2
  68. translate3d = `translate3d(${Math.round(x)}px,${Math.round(y)}px, 0)`
  69. }
  70. let scale3d = 'scale3d(1,1,1)'
  71. let scaleByDistance = this._style.scaleByDistance
  72. if (distance && scaleByDistance) {
  73. let nearValue = scaleByDistance.nearValue
  74. let farValue = scaleByDistance.farValue
  75. let f = distance / scaleByDistance.far
  76. if (distance < scaleByDistance.near) {
  77. scale3d = `scale3d(${nearValue},${nearValue},1)`
  78. } else if (distance > scaleByDistance.far) {
  79. scale3d = `scale3d(${farValue},${farValue},1)`
  80. } else {
  81. let scale = farValue + f * (nearValue - farValue)
  82. scale3d = `scale3d(${scale},${scale},1)`
  83. }
  84. }
  85. let distanceDisplayCondition = this._style.distanceDisplayCondition
  86. if (distance && distanceDisplayCondition) {
  87. this.show =
  88. this._show &&
  89. isBetween(
  90. distance,
  91. distanceDisplayCondition.near,
  92. distanceDisplayCondition.far
  93. )
  94. }
  95. this._delegate.style.transform = `${translate3d} ${scale3d}`
  96. }
  97. /**
  98. *
  99. * @param layer
  100. * @returns {boolean}
  101. * @private
  102. */
  103. _onAdd(layer) {
  104. this._layer = layer
  105. this._layer.delegate.appendChild(this._delegate)
  106. this._delegate.addEventListener('click', () => {
  107. this._overlayEvent.fire(MouseEventType.CLICK, {
  108. layer: layer,
  109. overlay: this,
  110. position: Transform.transformWGS84ToCartesian(this._position)
  111. })
  112. })
  113. this._state = State.ADDED
  114. }
  115. /**
  116. *
  117. * @private
  118. */
  119. _onRemove() {
  120. if (this._layer) {
  121. this._layer.delegate.removeChild(this._delegate)
  122. this._state = State.REMOVED
  123. }
  124. }
  125. /**
  126. * Sets text
  127. * @param text
  128. * @param textStyle
  129. * @returns {DivIcon}
  130. */
  131. setLabel(text, textStyle) {
  132. return this
  133. }
  134. /**
  135. * Sets style
  136. * @param style
  137. * @returns {DivIcon}
  138. */
  139. setStyle(style) {
  140. if (!style || Object.keys(style).length === 0) {
  141. return this
  142. }
  143. this._style = style
  144. this._style.className &&
  145. DomUtil.addClass(this._delegate, this._style.className)
  146. return this
  147. }
  148. /**
  149. * Parse from entity
  150. * @param entity
  151. * @param content
  152. * @returns {DivIcon}
  153. */
  154. static fromEntity(entity, content) {
  155. let divIcon
  156. let now = Cesium.JulianDate.now()
  157. let position = Transform.transformCartesianToWGS84(
  158. entity.position.getValue(now)
  159. )
  160. divIcon = new DivIcon(position, content)
  161. if (entity.billboard) {
  162. divIcon.attr = {
  163. ...entity?.properties?.getValue(now)
  164. }
  165. }
  166. return divIcon
  167. }
  168. }
  169. Overlay.registerType('div_icon')
  170. export default DivIcon