您的位置:首页 > Web前端

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

2018-02-02 10:58 579 查看
以往通过前端绘制的方式实现矢量地图的可视化,往往是使用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实现的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: