概述
在前文完成了mapboxGL中区域掩膜的实现。近日有人问到说在openlayers中如何实现,本文就带大家看看如何在openlayers中实现区域掩膜。
实现效果
实现
1. 实现思路
- 在地图容器中添加一个
canvas
,设置其在map之上; - 监听map的
postrender
事件,每次事件触发重新绘制掩膜; - 通过map.getPixelFromCoordinate实现地理坐标到屏幕坐标的转换;
- 通过globalCompositeOperation = 'source-out’设置反向裁剪;
2. 实现代码
1. 添加canvas
const { offsetWidth, offsetHeight } = map.getViewport()
canvas = document.createElement('canvas');
canvas.width = offsetWidth;
canvas.height = offsetHeight;
canvas.style.position = 'absolute';
canvas.style.top = '0px';
canvas.style.left = '0px';
canvas.style.zIndex = '1';
ctx = canvas.getContext('2d');
map.getViewport().appendChild(canvas);
2. 注册map事件
map.on('postrender', e => {
addMapModal()
})
3. 事件实现
function addMapModal(params) {
const { fillStyle, strokeStyle, lineWidth } = {
fillStyle: 'rgba(255,255,255,0.8)',
strokeStyle: '#f00',
lineWidth: 3,
...params
}
ctx.fillStyle = fillStyle;
ctx.strokeStyle = strokeStyle;
ctx.lineWidth = lineWidth;
ctx.clearRect(0, 0, canvas.width, canvas.height)
const coords = modalData.map(coord => {
return map.getPixelFromCoordinate(ol.proj.fromLonLat(coord))
})
ctx.beginPath();
coords.forEach((coord, index) => {
index === 0 ? ctx.moveTo(coord[0], coord[1]) : ctx.lineTo(coord[0], coord[1])
})
ctx.closePath();
ctx.fill();
ctx.globalCompositeOperation = 'source-out';
ctx.rect(0, 0, canvas.width, canvas.height)
ctx.fill();
ctx.globalCompositeOperation = 'source-over';
ctx.beginPath();
coords.forEach((coord, index) => {
index === 0 ? ctx.moveTo(coord[0], coord[1]) : ctx.lineTo(coord[0], coord[1])
})
ctx.closePath();
ctx.stroke()
}