当前位置: 首页 > news >正文

使用openlayers给地图添加内发光、外发光、内外阴影、三维立体效果

给地图添加内阴影、外阴影效果,可以使用ol的扩展库ol-ext

npm i ol-ext

引入两个类Mask遮罩和Crop裁剪

import Mask from "ol-ext/filter/Mask";
import Crop from "ol-ext/filter/Crop.js";

Mask主要用来设置内阴影效果,外阴影则是由Crop设置。

addShadowByExt() {axios.get("https://geo.datav.aliyun.com/areas_v3/bound/110000.json").then((res) => {// 将 GeoJSON 数据解析为 ol.Feature 对象const features = new GeoJSON().readFeatures(res.data);const source = new VectorSource({features: features,});let layer = new VectorLayer({source: source,});this.map.addLayer(layer);//内发光let mask = this.addMask({fillColor: "#CC92E6",shadowColor: "#ff0",feature: features[0],inner: true,});//设置裁切this.setLayerFilterCrop(layer, features[0]);layer.addFilter(mask);});},//添加MaskaddMask(options) {return new Mask({feature: options.feature,wrapX: false,inner: options.inner || false,fill: new Fill({ color: options.fillColor }),shadowColor: options.shadowColor || "rgba(0,0,0,0.5)",shadowWidth: options.shadowWidth || 10,// shadowMapUnits:true,});},setLayerFilterCrop(layer, feature) {/*** 设置图层裁切*/const crop = new Crop({feature: feature,inner: false,active: true,wrapX: true,shadowWidth: 10,shadowColor: "#000",});layer.addFilter(crop);},

但是这种阴影不能调节偏移量,因此要设置阴影偏移量达到三维立体效果还需要利用canvas原理。

要想做出这种效果,需要在style的renderer函数中获取ctx上下文和图层用到的坐标数组coordinate。然后使用addOutlineShadow函数添加阴影。

我这里堆叠了好几层阴影,这样看着更立体些。

addRegionLayer() {let _this = this;const source = new VectorSource({url: "https://geo.datav.aliyun.com/areas_v3/bound/110000.json",format: new GeoJSON(),});this.vectorLayer = new VectorLayer({source: source,style: new Style({renderer(coordinate, state) {let arr = coordinate[0][0];const ctx = state.context;_this.addOutlineShadow(ctx, {fillStyle: "rgba(30, 60, 95,1)",shadowOffsetY: 30,shadowOffsetX: 2,shadowColor: "rgba(30, 60, 95,1)",strokeStyle: "rgba(30, 60, 95,1)",coodArr: arr,});_this.addOutlineShadow(ctx, {fillStyle: "transparent",shadowOffsetY: 20,shadowOffsetX: 2,shadowColor: "rgba( 56, 113, 139,1)",strokeStyle: "rgba(30, 60, 95,1)",coodArr: arr,});_this.addOutlineShadow(ctx, {fillStyle: "transparent",shadowOffsetY: 15,shadowOffsetX: 2,shadowColor: "rgba(255,255,255,1)",strokeStyle: "rgba(30, 60, 95,1)",shadowBlur: 10,coodArr: arr,});_this.addOutlineShadow(ctx, {fillStyle: "transparent",shadowOffsetY: 10,shadowOffsetX: 2,shadowColor: "rgba(83, 173, 214,1)",strokeStyle: "rgba(83, 173, 214,1)",coodArr: arr,});_this.addOutlineShadow(ctx, {fillStyle: "transparent",shadowOffsetY: 8,shadowOffsetX: 2,shadowColor: "rgba(255,255,255,1)",strokeStyle: "rgba(255,255,255,1)",shadowBlur: 10,coodArr: arr,});_this.addOutlineShadow(ctx, {fillStyle: "#fff",shadowOffsetY: 5,shadowOffsetX: 2,shadowColor: "rgba(70, 133, 171,1)",strokeStyle: "rgba(70, 133, 171,1)",shadowBlur: 10,coodArr: arr,});//白色_this.addOutlineShadow(ctx, {fillStyle: "rgba(70, 133, 171,1)",shadowOffsetY: 5,shadowOffsetX: 10,shadowColor: "rgba(255,255,255,1)",strokeStyle: "#50e3ff",shadowBlur: 15,coodArr: arr,lineWidth: 2,});},}),});this.map.addLayer(this.vectorLayer);},

 拿到canvas上下文了,就可以使用canvas的方法添加阴影效果了,最后再将拿到的坐标数组用canvas的方法绘制成多边形,就可以在地图上显示了。

事实上,这种方法不仅能绘制阴影,还可以绘制其他效果。

addOutlineShadow(ctx, option) {// 设置属性控制图形的外观ctx.fillStyle = option.fillStyle || "transparent";ctx.strokeStyle = option.strokeStyle || "transparent";ctx.lineWidth = option.lineWidth || 1;//  设置Y轴偏移量ctx.shadowOffsetY = option.shadowOffsetY || 20;//  设置X轴偏移量ctx.shadowOffsetX = option.shadowOffsetX || 2;//  设置模糊度ctx.shadowBlur = option.shadowBlur || 2;//  设置阴影颜色ctx.shadowColor = option.shadowColor || "#000";ctx.beginPath();let arr = option.coodArr || [];for (let i = 0; i < arr.length; i++) {const data = arr[i];if (i === 0) {ctx.moveTo(data[0], data[1]);} else {ctx.lineTo(data[0], data[1]);}}ctx.closePath();ctx.fill();ctx.stroke();},

完整代码:

<template><div class="box"><h1>给地图添加内发光、外发光、内外阴影、三维立体效果</h1><div id="map"></div></div>
</template><script>
import GeoJSON from "ol/format/GeoJSON.js";
import Map from "ol/Map.js";
import View from "ol/View.js";
import { OSM, Vector as VectorSource, XYZ } from "ol/source.js";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer.js";
import { Fill, Stroke, Text, Style } from "ol/style.js";
import { LineString, MultiPolygon, Point, Polygon } from "ol/geom.js";
import Mask from "ol-ext/filter/Mask";
import Crop from "ol-ext/filter/Crop.js";
import axios from "axios";
export default {name: "",components: {},data() {return {vectorLayer: null,map: null,};},computed: {},created() {},methods: {addShadowByExt() {axios.get("https://geo.datav.aliyun.com/areas_v3/bound/110000.json").then((res) => {// 将 GeoJSON 数据解析为 ol.Feature 对象const features = new GeoJSON().readFeatures(res.data);const source = new VectorSource({features: features,});let layer = new VectorLayer({source: source,});this.map.addLayer(layer);//内发光let mask = this.addMask({fillColor: "#CC92E6",shadowColor: "#ff0",feature: features[0],inner: true,});//设置裁切this.setLayerFilterCrop(layer, features[0]);layer.addFilter(mask);});},//添加MaskaddMask(options) {return new Mask({feature: options.feature,wrapX: false,inner: options.inner || false,fill: new Fill({ color: options.fillColor }),shadowColor: options.shadowColor || "rgba(0,0,0,0.5)",shadowWidth: options.shadowWidth || 10,// shadowMapUnits:true,});},setLayerFilterCrop(layer, feature) {/*** 设置图层裁切*/const crop = new Crop({feature: feature,inner: false,active: true,wrapX: true,shadowWidth: 10,shadowColor: "#000",});layer.addFilter(crop);},addRegionLayer() {let _this = this;const source = new VectorSource({url: "https://geo.datav.aliyun.com/areas_v3/bound/110000.json",format: new GeoJSON(),});this.vectorLayer = new VectorLayer({source: source,style: new Style({renderer(coordinate, state) {let arr = coordinate[0][0];const ctx = state.context;_this.addOutlineShadow(ctx, {fillStyle: "rgba(30, 60, 95,1)",shadowOffsetY: 30,shadowOffsetX: 2,shadowColor: "rgba(30, 60, 95,1)",strokeStyle: "rgba(30, 60, 95,1)",coodArr: arr,});_this.addOutlineShadow(ctx, {fillStyle: "transparent",shadowOffsetY: 20,shadowOffsetX: 2,shadowColor: "rgba( 56, 113, 139,1)",strokeStyle: "rgba(30, 60, 95,1)",coodArr: arr,});_this.addOutlineShadow(ctx, {fillStyle: "transparent",shadowOffsetY: 15,shadowOffsetX: 2,shadowColor: "rgba(255,255,255,1)",strokeStyle: "rgba(30, 60, 95,1)",shadowBlur: 10,coodArr: arr,});_this.addOutlineShadow(ctx, {fillStyle: "transparent",shadowOffsetY: 10,shadowOffsetX: 2,shadowColor: "rgba(83, 173, 214,1)",strokeStyle: "rgba(83, 173, 214,1)",coodArr: arr,});_this.addOutlineShadow(ctx, {fillStyle: "transparent",shadowOffsetY: 8,shadowOffsetX: 2,shadowColor: "rgba(255,255,255,1)",strokeStyle: "rgba(255,255,255,1)",shadowBlur: 10,coodArr: arr,});_this.addOutlineShadow(ctx, {fillStyle: "#fff",shadowOffsetY: 5,shadowOffsetX: 2,shadowColor: "rgba(70, 133, 171,1)",strokeStyle: "rgba(70, 133, 171,1)",shadowBlur: 10,coodArr: arr,});//白色_this.addOutlineShadow(ctx, {fillStyle: "rgba(70, 133, 171,1)",shadowOffsetY: 5,shadowOffsetX: 10,shadowColor: "rgba(255,255,255,1)",strokeStyle: "#50e3ff",shadowBlur: 15,coodArr: arr,lineWidth: 2,});},}),});this.map.addLayer(this.vectorLayer);},addOutlineShadow(ctx, option) {// 设置属性控制图形的外观ctx.fillStyle = option.fillStyle || "transparent";ctx.strokeStyle = option.strokeStyle || "transparent";ctx.lineWidth = option.lineWidth || 1;//  设置Y轴偏移量ctx.shadowOffsetY = option.shadowOffsetY || 20;//  设置X轴偏移量ctx.shadowOffsetX = option.shadowOffsetX || 2;//  设置模糊度ctx.shadowBlur = option.shadowBlur || 2;//  设置阴影颜色ctx.shadowColor = option.shadowColor || "#000";ctx.beginPath();let arr = option.coodArr || [];for (let i = 0; i < arr.length; i++) {const data = arr[i];if (i === 0) {ctx.moveTo(data[0], data[1]);} else {ctx.lineTo(data[0], data[1]);}}ctx.closePath();ctx.fill();ctx.stroke();},},mounted() {const view = new View({projection: "EPSG:4326",center: [116.389, 39.903],zoom: 7,});this.map = new Map({layers: [],target: "map",view: view,});this.addRegionLayer();// this.addShadowByExt();},
};
</script><style lang="scss" scoped>
#map {width: 100%;height: 500px;
}
.box {height: 100%;
}
</style>

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 可乐机的设计验证
  • 125. 验证回文串【 力扣(LeetCode) 】
  • 设计模式 - 状态模式
  • 详解使用Goalng+Redis实现分布式锁
  • haralyzer 半自动,一次性少量数据采集快捷方法
  • C++系列-继承中的对象模型
  • Spring Boot 使用 MongoDB 教程
  • SpringBoot日志整合
  • 大数据-70 Kafka 高级特性 物理存储 日志存储 日志清理: 日志删除与日志压缩
  • 第五天:java网络编程、JDBC与高级特性概览
  • 推荐一个根据后台提供的接口json文件自动生成前端调用接口的插件typescript
  • Mysql基础篇
  • Java高级Day28-让坦克动起来
  • 保命指南,家里有浮毛、异味竟会危害健康?去浮毛空气净化器推荐
  • vue的混入介绍
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • Angular 4.x 动态创建组件
  • JavaScript 一些 DOM 的知识点
  • laravel 用artisan创建自己的模板
  • Linux各目录及每个目录的详细介绍
  • Linux中的硬链接与软链接
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • Spring框架之我见(三)——IOC、AOP
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 京东美团研发面经
  • 什么软件可以剪辑音乐?
  • 实现菜单下拉伸展折叠效果demo
  • 微信开放平台全网发布【失败】的几点排查方法
  • 学习笔记TF060:图像语音结合,看图说话
  • 你对linux中grep命令知道多少?
  • MyCAT水平分库
  • 湖北分布式智能数据采集方法有哪些?
  • ​埃文科技受邀出席2024 “数据要素×”生态大会​
  • ​马来语翻译中文去哪比较好?
  • # Apache SeaTunnel 究竟是什么?
  • #Z2294. 打印树的直径
  • $.proxy和$.extend
  • (06)金属布线——为半导体注入生命的连接
  • (12)Linux 常见的三种进程状态
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (Windows环境)FFMPEG编译,包含编译x264以及x265
  • (阿里云在线播放)基于SpringBoot+Vue前后端分离的在线教育平台项目
  • (备忘)Java Map 遍历
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (三)docker:Dockerfile构建容器运行jar包
  • (三十)Flask之wtforms库【剖析源码上篇】
  • (十八)SpringBoot之发送QQ邮件
  • (原)本想说脏话,奈何已放下
  • (转)甲方乙方——赵民谈找工作
  • .NET Core WebAPI中封装Swagger配置
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .net对接阿里云CSB服务
  • .net实现头像缩放截取功能 -----转载自accp教程网