前端OpenLayers实现阴影效果(canvas绘制)

以往通过前端绘制的方式实现矢量地图的可视化,往往是使用ArcGIS的前端API,底层是通过svg的方式实现,优点,是可以使用svg的滤镜,css3等方式实现比较绚丽的地图可视化效果,比如,阴影,动画等,svg的内置filter很多很方便,缺点是使用svg的filter可能导致渲染速度变慢,如果是比较多的矢量点,可能导致效率低下,最近尝试使用canvas的方式是否也能实现类似效果,我所选择的前端API是OpenLayers4.6版本,底层只能是canvas或webgl,默认是canvas渲染,openLayers3以后的版本,已经放弃了低效的svg绘图,转为canvas,以前总觉得用canvas会很麻烦,滤镜的效果可能无法实现,或者实现起来很费劲,接口可能没有开放出来,通过这次的尝试,发现canvas也不是想象中的那么难用。

 下面举例说明,矢量地图加载,选中,高亮的要素,需要实现浮动的效果,svg的实现思路就是设置要素g的filter为

url(‘#shadow’),svg的滤镜很好实现,下面是代码:

<filter id="blurMe1">
    <feColorMatrix in="SourceAlpha" result="matrixOut" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
  <feGaussianBlur in="matrixOut" stdDeviation="5" our="blurOut"/>
    <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
 </filter>

然后是使用该滤镜的svg要数

<circle cx="280" cy="60" r="50" fill="green"
          filter="url(#blurMe1)" />

实现的效果,就是原始图增加高斯模糊滤镜,然后,上面叠加原始图,进行融合

图一是原始图,图二只有高斯模糊滤镜,图三是想要的浮动效果,组合而成,其实就是阴影效果啊

下面想要达到的效果


openlayers的实现思路就是,高亮的要数放到单独一个图层里面,然后设置该图层的阴影效果,这样不会影响其他层的

渲染

 addHighlightLayer(mapObj, layer) {
        if (layer) {
            mapObj.removeLayer(layer);
        }
        layer = new Vector({
            source: new SourceVector(),
            style: () => {
                const fill = new Fill({
                    color: 'raba(0,0,0,1)'
                });
                const style = new Style({
                    // fill:fill,
                    fill: fill,
                    stroke: new Stroke({
                        color: 'rgba(255, 255, 255, 1)',
                        width: 1
                    })
                });
                // fill.setColor(pattern);
                return style;
            }
        });
        mapObj.addLayer(layer);
        this.onBindLayerClick(layer);
        return layer;
    }

    onBindLayerClick(layer) {
        layer.on('precompose', evt => {
            evt.context.shadowBlur = 25;
            evt.context.shadowColor = 'black';
        });
        layer.on('postcompose', evt => {
            evt.context.shadowBlur = 0;
            evt.context.shadowColor = 'black';
        });
    }

然后就是高亮的时候,添加一个要素,有一点需要注意的是,需要动态设置高亮图层的样式为选中要数的原来样式,主要是填充颜色

                        map.highlightLayer.setStyle(
                            () => {
                                return new Style({
                                    fill: new Fill({ color: (f.style && f.style.getFill) ? f.style.getFill().getColor() : '#aaa' }),
                                    stroke: new Stroke({ color: 'rgba(255, 255, 255, 0.2)', width: 2 })
                                });
                            }
                        );
                        map.highlightLayer.getSource().addFeature(f);

总结:

动态设置样式的时候,只能是函数返回值方式,如果直接指定style对象,总报错。总体来说,实现效果很好,绘图速度很快,尤其在移动端浏览器依然可以通用,使用ArcGIS js API在启动的时候加载的资源文件比较大,大概2M,尤其在移动端,网速慢

情况下影响很大显示的很慢,改用openlayers实现就很快了,资源文件很小,可以动态打包进去,或者可以使用Leaflet实现,

Leaflet默认也是svg实现的。






转载自:https://blog.csdn.net/liyan_gis/article/details/79236192

You may also like...