OpenLayers 3 postcompose 到 Vue SPA 中的 OpenLayers 6 事件
OpenLayers 3 postcompose to OpenLayers 6 event in Vue SPA
我做了这个 codepen,我在 postcompose
上操作 OpenLayers 地图底图的上下文。我遇到的问题是将此工作演示转换为使用 OpenLayers 6 的 Vue SPA,我想 link 将暗模式映射效果切换为切换。 postcompose
事件在 OL6 中的触发方式与在 OL3 中的触发方式不同,因此我尝试连接到 prerender
.
import TileLayer from 'ol/layer/Tile';
...
osm: new TileLayer({source: new OSM()})
在 OpenLayers 3 中,以下代码为我提供了永久暗模式地图:
OSM_LAYER.on('postcompose', function (evt) {
evt.context.globalCompositeOperation = 'color';
evt.context.fillStyle = 'rgba(0,0,0,' + 1.0 + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'overlay';
evt.context.fillStyle = 'rgb(' + [200,200,200].toString() + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'source-over';
document.querySelector('canvas').style.filter="invert(99%)";
});
目前我正在尝试按照 使用 getVectorContext
但我不理解某些东西,因为我的代码没有给我正确的暗模式:
OSM_LAYER.on('prerender', function (evt) {
var ctx = getVectorContext(evt).context_
ctx.globalCompositeOperation = ‘color’;
ctx.fillStyle = ‘rgba(0,0,0,’ + 1.0 + ‘)’;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.globalCompositeOperation = ‘overlay’;
ctx.fillStyle = ‘rgb(‘ + [200,200,200].toString() + ‘)’;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.globalCompositeOperation = ‘source-over’;
document.querySelector('canvas').style.filter="invert(99%)";
});
编辑:感谢 Mike 先生的回答,我能够复制 OL3 黑暗模式的外观。现在的问题是我实际上使用这个底图来创建一个动画,我在 for 循环中更新所有图层的时间参数,然后使用 :
提取地图 canvas
getMapCanvas () {
var mapCanvas = document.createElement('canvas');
var divElement = document.querySelector(".map");
mapCanvas.width = divElement.offsetWidth;//size[0];
mapCanvas.height = divElement.offsetHeight;//size[1];
var mapContext = mapCanvas.getContext('2d');
Array.prototype.forEach.call(
document.querySelectorAll('.ol-layer canvas'),
function (canvas) {
if (canvas.width > 0) {
const opacity = canvas.parentNode.style.opacity;
mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
const transform = canvas.style.transform;
const matrix = transform
.match(/^matrix\(([^\(]*)\)$/)[1] //eslint-disable-line
.split(',')
.map(Number);
CanvasRenderingContext2D.prototype.setTransform.apply(mapContext,matrix);
mapContext.drawImage(canvas, 0, 0);
}
}
);
return mapCanvas;
},
仅在 rendercomplete
承诺得到解决后调用。使用迈克先生的方法,我得到了一种奇怪的白色色调,而不是暗模式 OSM,我认为这是因为我在 getMapCanvas
函数中导出 canvas 的方式。有人可以帮我调试一下吗?
样式过滤器仅影响 canvas 在屏幕上的显示方式。要反转绘制的内容,需要 difference
带有白色填充的 globalCompositeOperation。
this.map.getLayers().getArray()[0].on(['postrender'], (evt) => {
if ( this.darkOSM !== null && this.darkOSM === false ) {
evt.context.globalCompositeOperation = 'color';
evt.context.fillStyle = 'rgba(0,0,0,' + 1.0 + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'overlay';
evt.context.fillStyle = 'rgb(' + [200,200,200].toString() + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'difference';
evt.context.fillStyle = 'rgba(255,255,255,' + 0.9 + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'source-over';
}
});
要使用 on
和 un
,您需要:
this.myFunction = (evt) => {
if ( this.darkOSM !== null && this.darkOSM === false ) {
evt.context.globalCompositeOperation = 'color';
evt.context.fillStyle = 'rgba(0,0,0,' + 1.0 + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'overlay';
evt.context.fillStyle = 'rgb(' + [200,200,200].toString() + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'difference';
evt.context.fillStyle = 'rgba(255,255,255,' + 0.9 + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'source-over';
}
};
this.map.getLayers().getArray()[0].on(['postrender'], this.myFunction);
this.map.getLayers().getArray()[0].un(['postrender'], this.myFunction);
如果您从 on
中保存密钥,则它必须与 unByKey
https://openlayers.org/en/latest/apidoc/module-ol_Observable.html#.unByKey
一起使用
我做了这个 codepen,我在 postcompose
上操作 OpenLayers 地图底图的上下文。我遇到的问题是将此工作演示转换为使用 OpenLayers 6 的 Vue SPA,我想 link 将暗模式映射效果切换为切换。 postcompose
事件在 OL6 中的触发方式与在 OL3 中的触发方式不同,因此我尝试连接到 prerender
.
import TileLayer from 'ol/layer/Tile';
...
osm: new TileLayer({source: new OSM()})
在 OpenLayers 3 中,以下代码为我提供了永久暗模式地图:
OSM_LAYER.on('postcompose', function (evt) {
evt.context.globalCompositeOperation = 'color';
evt.context.fillStyle = 'rgba(0,0,0,' + 1.0 + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'overlay';
evt.context.fillStyle = 'rgb(' + [200,200,200].toString() + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'source-over';
document.querySelector('canvas').style.filter="invert(99%)";
});
目前我正在尝试按照 getVectorContext
但我不理解某些东西,因为我的代码没有给我正确的暗模式:
OSM_LAYER.on('prerender', function (evt) {
var ctx = getVectorContext(evt).context_
ctx.globalCompositeOperation = ‘color’;
ctx.fillStyle = ‘rgba(0,0,0,’ + 1.0 + ‘)’;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.globalCompositeOperation = ‘overlay’;
ctx.fillStyle = ‘rgb(‘ + [200,200,200].toString() + ‘)’;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.globalCompositeOperation = ‘source-over’;
document.querySelector('canvas').style.filter="invert(99%)";
});
编辑:感谢 Mike 先生的回答,我能够复制 OL3 黑暗模式的外观。现在的问题是我实际上使用这个底图来创建一个动画,我在 for 循环中更新所有图层的时间参数,然后使用 :
提取地图 canvasgetMapCanvas () {
var mapCanvas = document.createElement('canvas');
var divElement = document.querySelector(".map");
mapCanvas.width = divElement.offsetWidth;//size[0];
mapCanvas.height = divElement.offsetHeight;//size[1];
var mapContext = mapCanvas.getContext('2d');
Array.prototype.forEach.call(
document.querySelectorAll('.ol-layer canvas'),
function (canvas) {
if (canvas.width > 0) {
const opacity = canvas.parentNode.style.opacity;
mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
const transform = canvas.style.transform;
const matrix = transform
.match(/^matrix\(([^\(]*)\)$/)[1] //eslint-disable-line
.split(',')
.map(Number);
CanvasRenderingContext2D.prototype.setTransform.apply(mapContext,matrix);
mapContext.drawImage(canvas, 0, 0);
}
}
);
return mapCanvas;
},
仅在 rendercomplete
承诺得到解决后调用。使用迈克先生的方法,我得到了一种奇怪的白色色调,而不是暗模式 OSM,我认为这是因为我在 getMapCanvas
函数中导出 canvas 的方式。有人可以帮我调试一下吗?
样式过滤器仅影响 canvas 在屏幕上的显示方式。要反转绘制的内容,需要 difference
带有白色填充的 globalCompositeOperation。
this.map.getLayers().getArray()[0].on(['postrender'], (evt) => {
if ( this.darkOSM !== null && this.darkOSM === false ) {
evt.context.globalCompositeOperation = 'color';
evt.context.fillStyle = 'rgba(0,0,0,' + 1.0 + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'overlay';
evt.context.fillStyle = 'rgb(' + [200,200,200].toString() + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'difference';
evt.context.fillStyle = 'rgba(255,255,255,' + 0.9 + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'source-over';
}
});
要使用 on
和 un
,您需要:
this.myFunction = (evt) => {
if ( this.darkOSM !== null && this.darkOSM === false ) {
evt.context.globalCompositeOperation = 'color';
evt.context.fillStyle = 'rgba(0,0,0,' + 1.0 + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'overlay';
evt.context.fillStyle = 'rgb(' + [200,200,200].toString() + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'difference';
evt.context.fillStyle = 'rgba(255,255,255,' + 0.9 + ')';
evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
evt.context.globalCompositeOperation = 'source-over';
}
};
this.map.getLayers().getArray()[0].on(['postrender'], this.myFunction);
this.map.getLayers().getArray()[0].un(['postrender'], this.myFunction);
如果您从 on
中保存密钥,则它必须与 unByKey
https://openlayers.org/en/latest/apidoc/module-ol_Observable.html#.unByKey