openlayers 行政区划 鼠标移入 圆扩散动画 打点

在这里插入图片描述

封装了一个类似全局动画控制器的类 用于播放所有动画

  	// 动画播放总控制器
    class animationSupper {
        funList = {}//所有的动画
        //修改动画
        setAnimationAct(animationAct) {
            this.funList.map(item => {
                item.animationAct()
            })
            this.setAnimationAct = animationAct
            return this
        }

        //动画播放方法
        animationFun() {
            if (!Object.keys(this.funList).length) return
            Object.values(this.funList).map(item => {
                item()
            })
            requestAnimationFrame(() => this.animationFun())
        }

        // 修改动画
        setFun(keyValue, fun) {
            let key = keyValue ? keyValue : Math.random()
            this.funList[key] = fun
            this.animationFun()
            return key
        }

        //添加动画
        addFun(fun) {
            let key = Math.random()
            this.funList[key] = fun
            this.animationFun()
            return key
        }

        //删除动画
        removeFun(key) {
            delete this.funList[key]
        }
    }

单个动画控制类

	//下面的控制器要用到这个实例化后的类
	let ani = new animationSupper()
    // 动画控制器
    class animation {
        geometry
        animationAct
        //掩饰时间
        timer = 1
        //动画携带数据
        columnData
        //播放状态控制
        status = false
        //每个动画专有的key
        funKey

        //入口需要传入图形 和动画方法
        constructor(geometry, animationAct) {
            this.geometry = geometry
            this.animationAct = animationAct
            return this

        }

        //修改某个动画携带的数据
        setCoumnData(columnData) {
            this.columnData = columnData
            return this
        }

        //修改动画时间
        setTimer(timer) {
            this.timer = timer
            return this
        }

        //更改动画
        setAnimationAct(animationAct) {
            this.animationAct = animationAct
            ani.setFun(this.funKey, () => this.animationAct(this.columnData))
            return this
        }

        //开始动画
        start() {
            this.status = true
            setTimeout(() => {
                this.funKey = ani.addFun(() => this.animationAct(this.columnData))
            }, this.timer)
            return this
        }

        //停止动画
        stop() {
            ani.removeFun(this.funKey)
            this.status = false
        }
    }

基础地图


    let map = new ol.Map({
        target: "map",
        view: new ol.View({
            center: [112.549248, 37.857014],
            zoom: 5,
            projection: "EPSG:4326",
        }),
        layers: [],
    })

文字图层相关内容

 	//新建空的文字图层 名字为了方便控制
    let textLayer = new ol.layer.Vector({
        name: "text",
        zIndex: 3,//进行图层层次控制
        source: new ol.source.Vector(),
    })
     /**
     * 创建一个文字 返回文字要素 需要传入坐标点 及文字内容
     * @param {[number,number]} xy 坐标
     * @param {string} text 渲染的文字
     * @returns {Feature} 要素
     */
    function addText(xyz, text) {
        //新建要素 点的位置为
        let feature = new ol.Feature({
            //几何为一个点 位置在xy
            geometry: new ol.geom.Point(xyz)
        });
        //修改样式为文字
        feature.setStyle(new ol.style.Style({
            text: new ol.style.Text({
                text: text,//文字内容为传入的text
                font: '16px Calibri,sans-serif',//字体大小和字体样式
                fill: new ol.style.Fill({color: '#fff'}),//填充样式
                offsetY: -18//位置偏移 有y就有x
            })
        }));
        return feature
    }
    map.addLayer(textLayer)

点图层的相关内容

	 //新建空的点图层 名字为了方便控制 
    let pointLayer = new ol.layer.Vector({
        name: "point",
        zIndex: 2, //进行图层层次控制
        source: new ol.source.Vector()
    })
     /**
     * 创建一个圆 返回圆的要素 需要传入坐标点
     * @param {[number,number]} xy 坐标
     * @returns {Feature} 要素
     */
    function addCircle(xy) {
        // 创建一个圆点要素
        let a = new ol.Feature({
            //几何对象为一个点 位置在xy
            geometry: new ol.geom.Point(xy),
        });
        //修改创建的要素样式为圆
        a.setStyle(new ol.style.Style({
            image: new ol.style.Circle({
                //半径为3
                radius: 3,
                //填充颜色
                fill: new ol.style.Fill({
                    color: 'rgba(255,1,1,0.3)'
                }),
            })
        }))
        return a
    }
	map.addLayer(pointLayer)

行政区划 部分内容 geojson文件地址

 	//原本样式 这里提出来为了下面的移入样式做准备
    let geoStyle = new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: '#eee',
            width: 1
        }),
        fill: new ol.style.Fill({
            color: '#d1d1d1'
        })
    })
    //选中的样式 为下面的移入样式做准备
    let selectStyle = new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: '#eee',
            width: 1
        }),
        fill: new ol.style.Fill({
            color: '#92959e'
        }),
    })
    //新建 行政区划geojson name为了下面选中的时候不影响其他图层
    let geoLayer = new ol.layer.Vector({
        name: "geoLayer",
        index: 1,//进行图层层次控制
        source: new ol.source.Vector({
            url: './province.geojson',//放你的地址
            format: new ol.format.GeoJSON()
        }),
        style: geoStyle
    })
    map.addLayer(geoLayer)

添加点和文字的方法 不需要的可以在里面删除掉 某个方法的调用 不需要点的动画就直接将addCircle返回的内容添加到pointLayer

	//添加点和文字的方法
    let initTextAndPoint = (event) => {
        //在所有的要素中遍历
        event.target.getFeatures().map(item => {
                //获取要素属性
                let data = item.getProperties()
                //获取到各省市的中心点
                if (data.center || data.centroid) {
                    //在文字图层获取数据源 且在数据源中添加要素 添加的要素为addText的返回内容 传入的文字裁掉 省|特别行政区|自治区
                    textLayer.getSource().addFeature(addText(data.center || data.centroid, data.name.replace(/省|特别行政区|自治区/g, '')))
                    //获取Circle画的圆要素
                    let geometry = addCircle(data.center || data.centroid)
                    //将这个要素添加到点图层
                    pointLayer.getSource().addFeatures([geometry])
                    //使用刚才创建的动画类 创建一个动画
                    let an = new animation(geometry, ({radius, status}) => {
                            //如果我们添加进去的 radius 半径大于10 我们将数据还原为0
                            if (radius > 10)
                                an.setCoumnData({
                                    radius: 0
                                })
                            else {
                                //否则将数据++ 这里加的值越大 速度越快
                                an.setCoumnData({
                                    radius: radius + 0.005
                                })
                            }
                            //捕获错误
                            try {
                                //获取到圆的style中的自定义styleImage 就是创建出来的样式源更改半径
                                geometry.getStyle().getImage().setRadius(radius)
                                //再更改源的style 实现动画
                                geometry.setStyle(geometry.getStyle())
                            } catch (e) {
                                //如果出错则停止动画
                                an.stop()
                            }
                        }
                    )
                    //更改延迟执行时间
                    an.setTimer(Math.random() * 1000)
                    //修改自定义数据 且开始动画
                    an.setCoumnData({
                        radius: 0,
                    }).start()
                }
            }
        )
        // 停止监听数据源更改 否则此方法一直调用
        geoLayer.getSource().un('change', initTextAndPoint)
    }
    //监听数据源修改 调用添加点和文字方法
    geoLayer.getSource().on('change', initTextAndPoint)

鼠标移入 更改颜色 代码

 	//鼠标移入的选中项
    let selectFeature = null
    let selectId = null
    //监听鼠标移动
    map.on('pointermove', function (event) {
        //从map中获取到像素位置下的要素
        map.forEachFeatureAtPixel(event.pixel, (feature, layer) => {
            //如果图层为geoLayer并且不是上一次选中的要素
            if (selectId != feature.ol_uid && layer.get('name') == 'geoLayer' && feature) {
                //如果选中的要素有则还原style 且将其他设置为空
                if (selectFeature) {
                    selectFeature.setStyle(geoStyle)
                    selectFeature = null
                    selectId = null
                }
                // 将唯一id提出来 进行性能优化 避免下一次再更改样式
                selectId = feature.ol_uid
                //将给要素给到选中要素 为了下一次恢复使用
                selectFeature = feature
                //修改要素样式
                feature.setStyle(selectStyle)
            }
        });
    });
  • 14
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑕、疵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值