• OpenLayers线性渐变和中心渐变(径向渐变)


    1.前言

      OpenLayers官网有整个图层的渐变示例,但是没有单个要素的渐变示例,我们这里来补充一下。OpenLayers中的渐变是通过fill选项中实现的。fill选项可以传一个ColorLike,本质是通过Canvas实现的,此时ColorLike对应的是CanvasPatternCanvasGradient

    2.添加一个面要素

    const source = new VectorSource();
     let polygon = new Feature({
       geometry:new Polygon([
         [
           [106.542384,30.485627],
           [106.542384,40.485627],
           [117.542384,40.485627],
           [117.542384,30.485627],
           [106.542384,30.485627],
         ]
       ])
     });
     source.addFeature(polygon)
     const vectorLayer = new VectorLayer({
       source: source,
     });
     const map = new Map({
       layers: [vectorLayer],
       target: 'map',
       view: new View({
         center: [126.980366, 37.52654],
         zoom: 1,
         projection:'EPSG:4326'
       }),
     });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述

    3.线性渐变

    //import {DEVICE_PIXEL_RATIO} from 'ol/has'
    getLineGradientStyle(){
      const canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');
      const pixelRatio = DEVICE_PIXEL_RATIO;
      let gradient = context.createLinearGradient(0,0,1024*pixelRatio,0);
      let mainColor = '#56e90e';
      let secondColor = '#0e57e9';
      gradient.addColorStop(0,mainColor);
      gradient.addColorStop(1,secondColor);
      return gradient;
    }
    let style = new Style({
      fill:new Fill({
        color:this.getLineGradientStyle()
      })
    })
    polygon.setStyle(style)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    3.1 第一个注意点

      现在我们的要素在地图的正中间,能看到两个颜色之间的过渡。我们把地图左键进行移动一下,使得要素分别在最后边和最后边,然后再来看看效果。
    在这里插入图片描述
    在这里插入图片描述
      发现了什么?效果是变化的!所以我们的渐变策略是不太对的,渐变填充应该根据面的范围以及当前所处的位置来进行动态计算。具体来说就是要在createLinearGradient的时候去动态计算.现在我把渐变改成从【512,0】到【1024,0】的渐变,然后我们把地图往左移动,再看看效果

    let gradient = context.createLinearGradient(512*pixelRatio,0,1024*pixelRatio,0);
    
    • 1

    在这里插入图片描述
      这次发现了什么?貌似始终是在【512,0】到【1024,0】渐变。但如果你真的这样以为了,那你就错了。现在把地图往右移动,看看会发生什么事?
    在这里插入图片描述
      好像渐变的位置发生了偏移,不是我们最初设定的【512,0】到【1024,0】了。为什么挥发生这种现象。我们来看OpenLayers官网是是怎么解释的。在OpenLayers官网关于渐变有这样一段描述:
    在这里插入图片描述
    翻译过来就是

    CanvasRenderingContext2D.fillStyle或CanvasRendering Context2D.strokeStyle接受的类型。表示颜色、图案或渐变。图案和渐变作为填充样式的原点是从地图坐标[0,0]增加512个css像素。对于无缝重复图案,图案图像的宽度和高度必须是两倍(2,4,8,…,512)。

      重点是这一句:图案和渐变作为填充样式的原点是从地图坐标[0,0]增加512个css像素
      也就是说这个[0,0]是屏幕坐标,不是我们以为的经纬度坐标。而且渐变的位置也不是我们想要的,我们想要的是从某个经纬度到某个经纬度的渐变。

    3.2 第二个注意点

      512个css像素是什么意思?
      :屏幕在出厂时就从硬件上面决定了,用几个物理像素来代表一个css像素。因此才有设备像素比这个参数,也就是我们上文导入的DEVICE_PIXEL_RATIO

    4.中心渐变(径向渐变)

    getCenterGradientStyle(polygon){
      let canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');
      let extent = polygon.getExtent()
      let minLon = extent[0]
      let maxLon = extent[2]
      let minLat = extent[1]
      let maxLat = extent[3]
      let resolution = this.map.getView().getResolution()
      const pixelRatio = DEVICE_PIXEL_RATIO;
      let height = (maxLat - minLat)/resolution*pixelRatio
      let width = (maxLon-minLon)/resolution*pixelRatio
      canvas.width = width
      canvas.height = height
      let radius = Math.max(height,width)
      let center = map.getPixelFromCoordinate([
        (minLon+maxLon)/2,
        (maxLat+minLat)/2
      ])
      let gradient = context.createRadialGradient(
        center[0],
        center[1],
        radius/6,
        center[0],
        center[1],
        radius/2
      )
      let mainColor = '#56e90e';
      let secondColor = '#0e57e9';
      gradient.addColorStop(0,mainColor);
      gradient.addColorStop(1,secondColor);
      return gradient;
    }
    let style = new Style({
      fill:new Fill({
        color:this.getCenterGradientStyle()
      })
    })
    polygon.setStyle(style)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    在这里插入图片描述

    在change:resolution事件中去调用,保证算出来的宽高的正确性

    5.总结

      OpenLayers中的渐变效果实在很难令人满意,又或者是我们理解的有问题,因为其是动态变化的,我们很难得到想要的结果。目前,我们要时刻注意监听视图的变化来修改渐变的效果。本文算是抛砖引玉吧,如果某位有志之士能谁能解决掉这个问题,希望能告诉我一下,回见~

  • 相关阅读:
    Git 传文件到github
    架构师日记-33个常见编码漏洞大揭秘
    算法通关村第一关|黄金挑战|链表中的环问题&双向链表
    Java_异常详解
    【牛客SQL必知必会 3天热身】01. 基本的检索、排序、过滤
    tomcat安装、部署JSPGOU项目、Tomcat多实例
    Android - OkHttp 访问 https 的怪问题
    使用Linux远程连接OpenGauss数据库的步骤和方法
    Django全家桶
    基于Python+SQLSERVER的快递业务管理系统的设计与实现
  • 原文地址:https://blog.csdn.net/xiangshangdemayi/article/details/136351896