callout.js 5.2 KB
Newer Older
1
import { IS_AMAP } from '../../../../helpers/location'
DCloud-WZF's avatar
DCloud-WZF 已提交
2

Q
qiang 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15
export function createCallout (maps) {
  function onAdd () {
    const div = this.div
    const panes = this.getPanes()
    panes.floatPane.appendChild(div)
  }
  function onRemove () {
    const parentNode = this.div.parentNode
    if (parentNode) {
      parentNode.removeChild(this.div)
    }
  }

DCloud-WZF's avatar
DCloud-WZF 已提交
16 17 18 19 20
  function createAMapText () {
    const option = this.option
    this.Text = new maps.Text({
      text: option.content,
      anchor: 'bottom-center', // 设置文本标记锚点
21
      offset: new maps.Pixel(0, option.offsetY - 16),
DCloud-WZF's avatar
DCloud-WZF 已提交
22 23 24 25 26 27 28 29 30 31 32 33 34
      style: {
        padding: (option.padding || 8) + 'px',
        'line-height': (option.fontSize || 14) + 'px',
        'border-radius': (option.borderRadius || 0) + 'px',
        'border-color': `${option.bgColor || '#fff'} transparent transparent`,
        'background-color': option.bgColor || '#fff',
        'box-shadow': '0 2px 6px 0 rgba(114, 124, 245, .5)',
        'text-align': 'center',
        'font-size': (option.fontSize || 14) + 'px',
        color: option.color || '#000'
      },
      position: option.position
    })
35 36 37 38 39 40
    // 不通过 addListener 方式绑定事件,为了规避高德地图覆盖物点击触发map点击问题
    this.Text.dom.addEventListener('click', e => {
      handleAMapTextClick(this, e)
    })
    this.Text.dom.addEventListener('touchend', e => {
      handleAMapTextClick(this, e)
DCloud-WZF's avatar
DCloud-WZF 已提交
41 42 43 44 45
    })

    this.Text.setMap(option.map)
  }

46 47 48 49 50
  function handleAMapTextClick (self, e) {
    self.callback(e, self.parent)
    e.stopPropagation()
  }

DCloud-WZF's avatar
DCloud-WZF 已提交
51
  function removeAMapText () {
52 53 54
    if (this.Text) {
      this.option.map.remove(this.Text)
    }
DCloud-WZF's avatar
DCloud-WZF 已提交
55 56
  }

Q
qiang 已提交
57 58 59 60 61 62 63 64
  class Callout {
    option
    position
    index
    visible
    alwaysVisible
    div
    triangle
DCloud-WZF's avatar
DCloud-WZF 已提交
65 66 67
    callback
    parent
    Text
Q
qiang 已提交
68 69 70 71 72 73 74 75 76

    set onclick (callback) {
      this.div.onclick = callback
    }

    get onclick () {
      return this.div.onclick
    }

DCloud-WZF's avatar
DCloud-WZF 已提交
77
    constructor (option = {}, callback, parent) {
Q
qiang 已提交
78
      this.option = option || {}
DCloud-WZF's avatar
DCloud-WZF 已提交
79
      this.visible = this.alwaysVisible = option.display === 'ALWAYS'
80
      if (IS_AMAP) {
DCloud-WZF's avatar
DCloud-WZF 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
        this.callback = callback
        this.parent = parent
        if (this.visible) {
          this.createAMapText()
        }
      } else {
        const map = option.map
        this.position = option.position
        this.index = 1
        const div = (this.div = document.createElement('div'))
        const divStyle = div.style
        divStyle.position = 'absolute'
        divStyle.whiteSpace = 'nowrap'
        divStyle.transform = 'translateX(-50%) translateY(-100%)'
        divStyle.zIndex = '1'
        divStyle.boxShadow = option.boxShadow || 'none'
        divStyle.display = this.visible ? 'block' : 'none'
        const triangle = (this.triangle = document.createElement('div'))
        triangle.setAttribute(
          'style',
          'position: absolute;white-space: nowrap;border-width: 4px;border-style: solid;border-color: #fff transparent transparent;border-image: initial;font-size: 12px;padding: 0px;background-color: transparent;width: 0px;height: 0px;transform: translate(-50%, 100%);left: 50%;bottom: 0;'
        )
        this.setStyle(option)
        div.appendChild(triangle)
        if (map) {
          this.setMap(map)
        }
Q
qiang 已提交
108 109 110
      }
    }

DCloud-WZF's avatar
DCloud-WZF 已提交
111 112 113
    createAMapText = createAMapText
    removeAMapText = removeAMapText

Q
qiang 已提交
114 115 116 117 118 119 120 121 122
    onAdd = onAdd
    construct = onAdd
    setOption (option) {
      this.option = option
      if (option.display === 'ALWAYS') {
        this.alwaysVisible = this.visible = true
      } else {
        this.alwaysVisible = false
      }
123
      if (IS_AMAP) {
DCloud-WZF's avatar
DCloud-WZF 已提交
124 125 126 127 128 129 130
        if (this.visible) {
          this.createAMapText()
        }
      } else {
        this.setPosition(option.position)
        this.setStyle(option)
      }
Q
qiang 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
    }

    setStyle (option) {
      const div = this.div
      const divStyle = div.style
      div.innerText = option.content || ''
      divStyle.lineHeight = (option.fontSize || 14) + 'px'
      divStyle.fontSize = (option.fontSize || 14) + 'px'
      divStyle.padding = (option.padding || 8) + 'px'
      divStyle.color = option.color || '#000'
      divStyle.borderRadius = (option.borderRadius || 0) + 'px'
      divStyle.backgroundColor = option.bgColor || '#fff'
      divStyle.marginTop = '-' + ((option.top || 0) + 5) + 'px'
      this.triangle.style.borderColor = `${option.bgColor || '#fff'} transparent transparent`
    }

    setPosition (position) {
      this.position = position
      this.draw()
    }

    draw () {
      const overlayProjection = this.getProjection()
      if (!this.position || !this.div || !overlayProjection) {
        return
      }
      const pixel = overlayProjection.fromLatLngToDivPixel(this.position)
      const divStyle = this.div.style
      divStyle.left = pixel.x + 'px'
      divStyle.top = pixel.y + 'px'
    }

    changed () {
      const divStyle = this.div.style
      divStyle.display = this.visible ? 'block' : 'none'
    }

    onRemove = onRemove

    destroy = onRemove
  }
172
  if (!IS_AMAP) {
DCloud-WZF's avatar
DCloud-WZF 已提交
173 174 175 176 177 178
    const prototype = Callout.prototype
    const overlay = new (maps.OverlayView || maps.Overlay)()
    for (const key in overlay) {
      if (!(key in prototype)) {
        prototype[key] = overlay[key]
      }
179 180
    }
  }
DCloud-WZF's avatar
DCloud-WZF 已提交
181

Q
qiang 已提交
182 183
  return Callout
}