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

目录

  • 1.前言
  • 2.添加一个面要素
  • 3.线性渐变
    • 3.1 第一个注意点
    • 3.2 第二个注意点
  • 4.中心渐变(径向渐变)
  • 5.总结

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'}),});

在这里插入图片描述

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)

在这里插入图片描述

3.1 第一个注意点

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

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

在这里插入图片描述
  这次发现了什么?貌似始终是在【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*pixelRatiolet width = (maxLon-minLon)/resolution*pixelRatiocanvas.width = widthcanvas.height = heightlet 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)

在这里插入图片描述

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

5.总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/713693.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python defaultdict

python中的dict是一个重要的数据类型,知道如何使用这个数据类型很简单,但是这个类型使用过程中容易进入一些误区,这篇文章主要对defaultdict方法的讲解,深入的了解dict数据类型。 字典(dictionary)数据类型…

编译链接实战(22)C/C++代码覆盖率统计报告生成

文章目录 GCOV 工具简介gcov 使用lcov相关编译选项 GCOV 工具简介 gcov是一个测试代码覆盖率的工具,它是 gcc 自带的查看代码覆盖率的工具。 与GCC结合使用,可以分析您的程序以帮助创建更高效、运行更快的代码,并发现程序中未经测试的部分。…

PCIE 4.0 L0s/L1/L2

L0是PCIE设备正常工作的状态,当设备链路处于非工作状态可以跳转大相应的低功耗状态,L0s是一种可以快速恢复到L0的低功耗状态;L1必须经过Reovery状态才可以恢复到L0状态;L2需要从Detect开始逐步进入到L0状态。它们的恢复时间依次延…

麒麟银河操作系统V10部署ffmpeg(也能用于Linux系统)

麒麟银河操作系统V10部署ffmpeg(也能用于Linux系统) 部署ffmpeg用来处理视频的各种操作 想使用ffmpeg,要先安装nasm,yasm,x264之后,否则会报错 nkvers 查看麒麟操作系统版本 cat /proc/version #查看linux版本信息 uname -a …

Android修行手册-Chaquopy中opencv、numpy的初步应用

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分…

SpringBoot源码解读与原理分析(三十八)SpringBoot整合WebFlux(一)WebFlux的自动装配

文章目录 前言第13章 SpringBoot整合WebFlux13.1 响应式编程与Reactor13.1.1 命令式与响应式13.1.2 异步非阻塞13.1.3 观察者模式13.1.4 响应性13.1.5 响应式流13.1.6 背压13.1.7 Reactor13.1.7.1 Publisher13.1.7.2 Subscriber13.1.7.3 Subscription13.1.7.4 Processor13.1.7.…

BF算法实现(Python,C++)

BF算法,即暴力(Brute Force)算法,是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符;若不相等,则比…

Leetcoder Day32| 贪心算法part05

763.划分字母区间 字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。 示例: 输入:S "ababcbacadefegdehijhklij"输出:[9,7…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 3月2日,星期六

每天一分钟,知晓天下事! 2024年3月2日 星期六 农历正月廿二 1、 气象局:3月份仍有5次冷空气影响我国;全国多地或提前入春。 2、 央行:将外籍来华人员移动支付单笔交易限额由1000美元提高到5000美元。 3、 神舟十七号航…

全量知识系统问题及SmartChat给出的答复 之8 三套工具之3语法解析器 之1

Q19. 问题 : 解释单词解释单词occupied 的字典条目 (word-def occupiedinterest 5type EBsubclass SEBtemplate (script $Demonstrateactor nilobject nildemands nilmethod (scene $Occupyactor nillocation nil))fill (((actor) (top-of *actor-s…

【源码】imx6ull实现触摸屏单点实验

一、本实验实验的器材: 1.正点原子imx6ull的阿尔法开发板v2.2 2.屏幕ALIENTEK 4.3 RGBLCD 二、实验已经移植好的文件: 仓库代码:https://gitee.com/wangyoujie11/atkboard_-linux_-driver.git 1.文件说明 23_multitouch :驱动代…

aws平台的ec2实例 GNU/Linux系统安装docker流程

在AWS EC2实例上安装Docker的流程与其他GNU/Linux系统基本相同。以下是在AWS EC2实例上安装Docker的一般步骤: 登录到AWS EC2实例: 使用SSH或者其他远程登录方式登录到你的GNU/Linux实例。 更新系统包管理器: 对于基于Amazon Linux的系统&am…

常见Prometheus exporter部署

常见Prometheus exporter部署 Prometheus部署Node exporterProcess exporterRedis exporterMySQL exporterOracleDB exporter Prometheus部署 本地部署: wget https://github.com/prometheus/prometheus/releases/download/v*/prometheus-*.*-amd64.tar.gz tar xv…

java的jar打包docker镜像,启动加载

测试环境,打包镜像 1,把jar包复制/data/liu/mssda.jar, cd到这个目录下 2,创建Dockerfile文件,jdk17版本,内容如下 jdk8版本 FROM openjdk:8-jre-alpine WORKDIR /app COPY . /app CMD ["java", "-jar",…

最大奇约数(c++题解)

内存限制: 128 MiB时间限制: 100 ms标准输入输出题目类型: 传统评测方式: 文本比较 题目描述 定义函数f(x)表示x的最大奇约数,这里x表示正整数。例如,f(20) 5,因为20的约数从小到大分别有&am…

奥地利罗马尼亚媒体宣发稿对跨境出海推广新闻营销的意义

【本篇由言同数字科技有限公司原创】在当今全球化的时代,品牌跨境海外推广已成为企业拓展国际市场的必要途径。而奥地利和罗马尼亚是欧洲重要的市场之一,通过在当地媒体上发表文章,可以帮助品牌成功打入这两个市场,获得更多的机会…

【YOLO v5 v7 v8 小目标改进】ODConv:在卷积核所有维度(数量、空间、输入、输出)上应用注意力机制来优化传统动态卷积

ODConv:在卷积核所有维度(数量、空间、输入、输出)上应用注意力机制来优化传统的动态卷积 提出背景传统动态卷积全维动态卷积效果 小目标涨点YOLO v5 魔改YOLO v7 魔改YOLO v8 魔改 论文:https://openreview.net/pdf?idDmpCfq6Mg…

leedcode刷题--day7(字符串)

23 文章讲解 力扣地址 C class Solution { public:void reverseString(vector<char>& s) {int left 0;int right s.size() - 1; // right 应该初始化为 s.size() - 1while (left < right) {swap(s[left], s[right]); // 直接交换 s[left] 和 s[right] 的值lef…

(学习日记)2024.02.29:UCOSIII第二节

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

WSL2外部网络设置

1 关闭所有WSL系统 wsl --shutdown 2 打开Hyper-V管理器 3 将“虚拟交换机管理器”-> ”WSL连接类型“设置为“外部网络” 4 启动WSL系统&#xff0c;手动修改WSL网络 将WSL网络IP修改为192.168.1.9 sudo ip addr del $(ip addr show eth0 | grep inet\b | awk {print $2} |…