control/layerControl/index.js

class LayerControl {
    /**
     * 初始化
     * @param {Object} options 参数
     * @param {String} [options.pattern='v'] 排列方式 默认为垂直('v','h')
     * @param {String} [options.position='top-right] 位置 默认右上, 当排列方式为水平时, 自动居中.左右不产生实际效果
     * @param {Number} [options.size='60'] 图标尺寸
     * @param {Boolean} [options.check=false] 勾选框 默认不显示
     */
    constructor({ pattern = 'v', position = 'top-right', size = 60, check = false } = {}) {

        this.pattern = pattern;
        this.position = position;
        this.size = size;
        this.check=check;
        this._container = document.createElement('div');
        this._container.className = 'mapboxgl-ctrl';
        this._container.addEventListener('contextmenu', (e) => e.preventDefault());
        this.btn = document.createElement('ul');
        this.btn.className = 'mapboxgl-ctrl-ul';
        this._container.appendChild(this.btn);
        this.btn.addEventListener('click', (e) => {

            let target = e.target;
            if (target.tagName.toLowerCase() == "input") {
                if (target.checked) {
                    target.checked = false;
                } else {
                    target.checked = true;
                }
            }
            while (1 == 1) {
                if (target.tagName.toLowerCase() == 'li') {
                    break;
                }
                target = target.parentNode;
            }
            let checkNode = target.childNodes[0];
            let id = target.dataset.layerId;
            if (checkNode.checked) {

                this._map.setLayoutProperty(id, 'visibility', 'none');
                this._map.getLayer(id + '-hover') && this._map.setLayoutProperty(id + '-hover', 'visibility', 'visible');
                checkNode.checked = false;

            } else {

                this._map.setLayoutProperty(id, 'visibility', 'visible');
                this._map.getLayer(id + '-hover') && this._map.setLayoutProperty(id + '-hover', 'visibility', 'visible');
                checkNode.checked = true;

            }

        });

    }


    /**
     * 添加
     * @private
     * @param {*} map 
     */
    onAdd(map) {

        this._map = map;
        this._map.on('addLayer', e => {

            const layer = this._map.getLayer(e.json.id);
            if (layer.metadata && layer.metadata._LKey && layer.metadata._LKey === 'hyLayer') {

                const type = e.json.type;
                let li = document.createElement('li');
                li.id = 'li_' + e.id;
                li.dataset.layerId = e.id;
                li.className = 'mapboxgl-ctrl-li';
                let checkbox = document.createElement('input');
                checkbox.style.display = "none";
                if (this.check) {
                    checkbox.style.display = "";
                }
                checkbox.setAttribute('type', 'checkbox');
                checkbox.checked = true;
                checkbox.id = e.id;
                let canvas = document.createElement('canvas');
                canvas.width = this.size;
                canvas.height = this.size;
                canvas.className = 'mapboxgl-ctrl-canvas';
                let label = document.createElement('span');
                label.className = 'mapboxgl-ctrl-span';
                label.innerHTML = e.name;
                li.appendChild(checkbox);
                li.appendChild(canvas);
                li.appendChild(label);
                this.btn.appendChild(li);
                let ctx = canvas.getContext('2d');

                if (type === 'circle') {

                    ctx.beginPath();
                    let border=this.size/2
                    ctx.arc(border, border, border, 0, 360, false);
                    let color = e.json.paint['circle-color'];
                    if (typeof color === 'object') {

                        color = color.default;

                    }
                    ctx.fillStyle = color;//填充颜色,默认是黑色
                    ctx.fill();//画实心圆
                    ctx.closePath();

                } else if (type === 'symbol') {

                    const icon = e.json.layout['icon-image'];
                    const image = this._map.style.getImage(icon);
                    if (image) {

                        let imgData = new ImageData(new Uint8ClampedArray(image.data.data), image.data.width, image.data.height);
                        //创建临时层存放图片
                        let tmpcanvas = document.createElement('canvas');
                        tmpcanvas.width = image.data.width;
                        tmpcanvas.height = image.data.height;
                        let tctx = tmpcanvas.getContext('2d');
                        tctx.putImageData(imgData, 0, 0);
                        //创建image对象存放图片进行缩放
                        let imageObject = new Image();
                        imageObject.onload =  ()=> {

                            //缩放后放入展示层
                            ctx.scale(this.size / image.data.width,this.size/ image.data.height);
                            ctx.drawImage(imageObject, 0, 0);

                        };
                        imageObject.src = tmpcanvas.toDataURL();

                    }

                }

            }

        });
        this._map.on('removeLayer', e => {

            const li = document.querySelector('#li_' + e.id);
            this.btn.removeChild(li);

        });


        if (this.pattern === 'v') {


            return this._container;

        } else {

            if (this.position.indexOf('top') > -1) {

                this._container.className += ' mapboxgl-ctrl-top-center mapboxgl-ctrl-ul-h';

            } else {

                this._container.className += ' mapboxgl-ctrl-bottom-center mapboxgl-ctrl-ul-h';

            }

            const parent = document.querySelector('.mapboxgl-control-container');
            parent.appendChild(this._container);
            return document.createElement('div');

        }

    }
    /**
     * 移除时
     * @private
     */
    onRemove() {

        this._container.parentNode.removeChild(this._container);
        this._map = undefined;

    }
}

export default LayerControl;