Source: ext/control/PositionControl.js

import * as maptalks from '../../libs/maptalks'

class PositionControl extends maptalks.control.Control {
    /**
     * 鼠标位置控件类
     * @constructor
     * @param {Object} options 配置参数
     * @param {String} options.position 控件显示位置,目前支持左下:‘bottom-left’ 和右下:‘bottom-right’,默认为左下。
     * @param {Boolean} options.copiable 是否支持复制当前坐标,默认为true,支持复制、复制内容格式为:[x,y]。
     * @param {Object} options.styles 控件样式调整,目前支持调整背景颜色,字体颜色和字体大小
     * @param {String} options.styles.backgroundColor 控件背景颜色
     * @param {String} options.styles.fontColor 控件字体颜色
     * @param {String} options.styles.fontSize 控件字体大小
     */
    constructor (options = {}) {
        if (options.position === undefined) {
            options.position = 'bottom-left'
        }
        if (options.copiable === undefined) {
            options.copiable = true
        }
        if (options.styles === undefined) {
            options.styles = {}
        }
        super(options)
        this.options = options
    }

    /**
     * 生成控件
     * @param {Object} map maptalks原生地图对象
     * @returns {any} 控件dom对象
     */
    buildOn(map) {
        this.map = map

        const dom = maptalks.DomUtil.createEl('div', 'maptalks-position')
        this.options.styles.backgroundColor !== undefined && (dom.style.backgroundColor = this.options.styles.backgroundColor)
        this.options.styles.fontColor !== undefined && (dom.style.color = this.options.styles.fontColor)

        const span = maptalks.DomUtil.createEl('span', 'pos-ctrl-span')
        this.options.styles.fontSize !== undefined && (span.style.fontSize = this.options.styles.fontSize)
        this._span = span

        const copyBtn = maptalks.DomUtil.createEl('a', 'pos-ctrl-copy')
        copyBtn.href = 'javascript:;'
        const copyImg = maptalks.DomUtil.createEl('img', 'pos-img-copy')
        copyImg.src = 'images/copy.svg'
        this._copyBtn = copyBtn

        const resetBtn = maptalks.DomUtil.createEl('a', 'pos-ctrl-reset')
        resetBtn.href = 'javascript:;'
        const resetImg = maptalks.DomUtil.createEl('img', 'pos-img-reset')
        resetImg.src = 'images/reset.svg'
        this._resetBtn = resetBtn

        dom.appendChild(span)
        if (this.options.copiable) {
            copyBtn.appendChild(copyImg)
            dom.appendChild(copyBtn)
            resetBtn.appendChild(resetImg)
            dom.appendChild(resetBtn)
        }

        this.map.on('mousemove', this._update, this)
        this.map.on('click', this._pause, this)

        this._update()

        this._registerDomEvents()

        return dom
    }

    /**
     * 添加到地图
     * @param {Object} map maptalks原生地图对象或EasyMap对象
     * @returns {*} this
     */
    addTo(map) {
        if (map instanceof emap.EasyMap) {
            map = map.map
        }
        return super.addTo(map)
    }

    /**
     * 地图mousemove事件绑定的handler,实时更新坐标
     * @param e
     * @private
     */
    _update(e) {
        this._text = '[0,0]'
        if (e) {
            const _coordinate = e.coordinate.toArray().map(n => this._formatNtoS(n))
            this._text = `[${_coordinate[0]},${_coordinate[1]}]`
        }
        this._span.innerHTML = this._text
    }

    /**
     * 地图点击事件绑定的handler,移除mousemove事件使坐标暂停变化
     * @private
     */
    _pause() {
        this.map.off('mousemove', this._update, this)
    }

    /**
     * 注册复制按钮和重置按钮的dom事件
     * @private
     */
    _registerDomEvents() {
        if (this._copyBtn) {
            maptalks.DomUtil.addDomEvent(this._copyBtn, 'click', this._onCopyClick, this)
        }
        if (this._resetBtn) {
            maptalks.DomUtil.addDomEvent(this._resetBtn, 'click', this._onResetClick, this)
        }
    }

    /**
     * 点击复制按钮时,复制坐标
     * @private
     */
    _onCopyClick() {
        const flag = this._copyText(this._text)
        alert(flag ? "复制成功!" : "复制失败!")
    }

    /**
     * 点击重置按钮时,
     * @private
     */
    _onResetClick() {
        this.map.on('mousemove', this._update, this)
    }

    /**
     * 复制文本到剪贴板
     * @param {String} text 要复制的文本
     * @returns {boolean} 复制结果
     * @private
     */
    _copyText(text) {
        const textarea = document.createElement("input") // 创建input对象
        const currentFocus = document.activeElement // 当前获得焦点的元素
        document.body.appendChild(textarea) // 添加元素
        textarea.value = text
        textarea.focus()
        if (textarea.setSelectionRange) {
            textarea.setSelectionRange(0, textarea.value.length) // 获取光标起始位置到结束位置
        } else {
            textarea.select()
        }
        let flag = false
        try {
            flag = document.execCommand("copy") // 执行复制
        } catch(eo) {
            console.log('error')
        }
        document.body.removeChild(textarea) // 删除元素
        currentFocus.focus()
        return flag
    }

    _formatNtoS(number) {
        let text = String(number.toFixed(6))
        if (number >= 0) {
            text = ` ${text}`
        }
        if (Math.abs(number) < 10) {
            text = `&nbsp;&nbsp;${text}`
        } else if (Math.abs(number) < 100) {
            text = `&nbsp;${text}`
        }

        return text
    }
}

export default PositionControl