openlayer加载高德地图利用滤镜变成深色模式。
第一种思路是先把切片服务当做图片图层的数据源,然后修改图片数据源的参数,然后把修改过后的数据源通过图片图层加载到layers里面呈现。
下面是vue3的代码示例。
<template>
<div class="map-container">
<div ref="mapRef" class="map-container-view"></div>
</div>
</template>
<script setup>
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
import ImageLayer from 'ol/layer/Image';
import {Raster} from "ol/source.js";
import * as olProj from "ol/proj.js";
import {ref, onMounted} from 'vue';
// 坐标系
const projection = olProj.get('EPSG:4326');
// 高德切片服务
const baseLayer = new TileLayer({
//坐标系
projection,
source: new XYZ({
// 允许跨域
crossOrigin: 'anonymous',
wrapX: true,
url: 'https://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}',
})
})
// 栅格瓦片的Source
const sourceRaster = new Raster({
sources: [
//传入图层,这里是天地图矢量图或者天地图矢量注记
baseLayer
],
operationType: 'image',
operation: function (pixels, data) {
const pixelsTemp = pixels[0].data
//蓝色
for (var i = 0; i < pixelsTemp.length; i += 4) {
var r = pixelsTemp[i]
var g = pixelsTemp[i + 1]
var b = pixelsTemp[i + 2]
//运用图像学公式,设置灰度值
var grey = r * 0.3 + g * 0.59 + b * 0.11
//将rgb的值替换为灰度值
pixelsTemp[i] = grey
pixelsTemp[i + 1] = grey
pixelsTemp[i + 2] = grey
//基于灰色,设置为蓝色,这几个数值是我自己试出来的,可以根据需求调整
pixelsTemp[i] = 55 - pixelsTemp[i]
pixelsTemp[i + 1] = 255 - pixelsTemp[i + 1]
pixelsTemp[i + 2] = 305 - pixelsTemp[i + 2]
}
return pixels[0]
},
//线程数量
threads: 10
})
// 创建图层
const blueImageLayer = new ImageLayer({
name: "",
source: sourceRaster
});
下面给一个项目运行的效果图。
第二种方式是通过修改切片的加载图片的滤镜来实现。代码量比较少。
const baseLayer1 = new TileLayer({
//坐标系
projection,
source: new XYZ({
// 注意这里不能少 设置允许跨域
crossOrigin: 'anonymous',
wrapX: true,
url: 'https://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}',
tileLoadFunction: function (imageTile, src) {
// 使用滤镜 将白色修改为深色
let img = new Image()
// img.crossOrigin = ''
// 设置图片不从缓存取,从缓存取可能会出现跨域,导致加载失败
img.setAttribute('crossOrigin', 'anonymous')
img.onload = function () {
let canvas = document.createElement('canvas')
let w = img.width
let h = img.height
canvas.width = w
canvas.height = h
let context = canvas.getContext('2d')
context.filter =
'grayscale(20%) invert(95%) sepia(100%) hue-rotate(180deg) saturate(1000%) brightness(70%) contrast(100%)'
context.drawImage(img, 0, 0, w, h, 0, 0, w, h)
imageTile.getImage().src =
canvas.toDataURL('image/png')
}
img.src = src
}
})
})
下面给一张运行起来的效果图。
怎么样是不是很nice,这两种模式都是可以接受的,尤其是可以运用到炫酷的大屏项目里面。如果你get到了灵感不放动动发财的小手给小编一个赞呢 谢谢。
本文暂时没有评论,来添加一个吧(●'◡'●)