0

我正在使用 HTML 画布 drawImage 将 OSM 地图图块渲染到网页上。但是,如果最终用户选择了暗模式,我想降低这些显示地图的亮度,但仍然让它们对用户有意义。

到目前为止,我取得了一定的成功,如下:

  1. 首先使用 drawImage 绘制地图图块
  2. 将 globalCompositeOperation 设置为“差异”
  3. 使用相同大小的白色矩形过度绘制地图图块
  4. 将 globalCompositeOperation 设置回“source-over”

但这种简单的颜色反转也许不是最好的解决方案。有没有人有任何其他的建议。

4

3 回答 3

0

我找到了一个很好的解决方案,如下所示:

  1. 首先将画布上下文过滤器设置为“hue-rotate(180deg)”
  2. 然后使用 drawImage 在画布上绘制地图图块
  3. 然后将画布上下文过滤器设置为“无”
  4. 将画布上下文 globalCompositeOperation 设置为“差异”
  5. 然后用相同大小的白色矩形绘制地图图块
  6. 最后将画布上下文 globalCompositeOperation 设置回“source-over”
于 2019-12-04T13:08:12.360 回答
0

您可以切换到具有不同地图样式的不同切片服务器。检查例如来自Leaflet Provider DemoMapBox Light & Dark的“CartoDB.DarkMatter” 。

于 2019-12-02T10:28:15.690 回答
0

也许有人仍然会觉得这很有用,这是我在 tar1090 项目中为此目的使用的一些代码。负正反差可能很清晰,而暗淡基本上只是带有倒号的亮度修改。

切换功能:

function setDim(layer, state) {
    if (state) {
        layer.dimKey = layer.on('postrender', dim);
    } else {
        ol.Observable.unByKey(layer.dimKey);
    }
    OLMap.render();
}

后期渲染功能:

function dim(evt) {
    const dim = mapDimPercentage * (1 + 0.25 * toggles['darkerColors'].state);
    const contrast = mapContrastPercentage * (1 + 0.1 * toggles['darkerColors'].state);
    if (dim > 0.0001) {
        evt.context.globalCompositeOperation = 'multiply';
        evt.context.fillStyle = 'rgba(0,0,0,'+dim+')';
        evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
    } else if (dim < -0.0001) {
        evt.context.globalCompositeOperation = 'screen';
        console.log(evt.context.globalCompositeOperation);
        evt.context.fillStyle = 'rgba(255, 255, 255,'+(-dim)+')';
        evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
    }
    if (contrast > 0.0001) {
        evt.context.globalCompositeOperation = 'overlay';
        evt.context.fillStyle = 'rgba(0,0,0,'+contrast+')';
        evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
    } else if (contrast < -0.0001) {
        evt.context.globalCompositeOperation = 'overlay';
        evt.context.fillStyle = 'rgba(255, 255, 255,'+ (-contrast)+')';
        evt.context.fillRect(0, 0, evt.context.canvas.width, evt.context.canvas.height);
    }
    evt.context.globalCompositeOperation = 'source-over';
}

使用 LayerSwitcher 时的切换功能:

function setDimLayerSwitcher(state) {
    if (!state) {
        ol.control.LayerSwitcher.forEachRecursive(layers_group, function(lyr) {
                if (lyr.get('type') != 'base')
                return;
                ol.Observable.unByKey(lyr.dimKey);
                });
    } else {
        ol.control.LayerSwitcher.forEachRecursive(layers_group, function(lyr) {
                if (lyr.get('type') != 'base')
                return;
                lyr.dimKey = lyr.on('postrender', dim);
                });
    }
    OLMap.render();
}

于 2021-06-17T20:54:53.567 回答