【问题标题】:Rendering Maps on devices where Dark Mode has been selected在选择了深色模式的设备上渲染地图
【发布时间】:2020-03-26 08:05:00
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: html5-canvas openstreetmap ios-darkmode macos-darkmode android-darkmode


    【解决方案1】:

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

    【讨论】:

    • 您不一定需要使用 Leaflet 或 MapBox。如果您的代码支持 TMS 或 Mapbox GL,这些只是使用深色样式平铺服务器的 URL。
    • 这取决于您所指的具体地图库。基于矢量平铺的渲染引擎不必反转任何颜色,它们对深色主题地图使用完全不同的风格。相反,基于光栅图块的渲染引擎必须切换到不同的图块集或执行一些魔术转换,这必然会导致用户体验下降。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      也许有人仍然会觉得这很有用,这是我在 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();
      }
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 2013-01-15
        • 2018-07-28
        • 1970-01-01
        相关资源
        最近更新 更多