今天遇到了一点点的小情况,我自己根据leaflet.js做了一个离线地图,公司要用来做态势,但是地图的底图用的是高德的原图,样式是下面这样的:
但是态势的主题是如下的这种淡蓝色:
这就造成了本次的需求,需要可以修改样式的主题,由于本人是个后端小佬,前端菜鸡,所以实现起来发生了一些困难,这里简单介绍下实现的路程。
首先看下效果:
然后介绍下艰辛的过程:
首先,需要用到一个基于leaflet.js的插件:
https://github.com/hnrchrdl/leaflet-tilelayer-colorizr
但是在使用这个插件的时候出现了一些问题,这里不赘述了,大致就是我加载的地图瓦片是其他的服务器,但是这个插件似乎不能支持跨域,废了很大的心思我终于解决了这个问题。
这里我先提供解决的方式:
/* * L.TileLayer.Colorizr is a regular tilelayer with mapped colors. */ (function () { // L.TileLayer.Colorizr = var Colorizr = L.TileLayer.extend({ initialize: function (url, options) { options = L.extend({}, L.TileLayer.prototype.options, { colorize: function (pixel) { return pixel; }, crossOrigin: 'Anonymous' }, options); L.TileLayer.prototype.initialize.call(this, url, options); L.setOptions(this, options); this.setColorizr(this.options.colorize); this.on('tileload', function (e) { this._colorize(e.tile); }); }, setColorizr: function (colorizrFactory) { if (!colorizrFactory || typeof colorizrFactory !== 'function') { throw 'The colorize option should be a function and return an object with at least one of "r", "g", "b", or "a" properties. Got:' + typeof colorizrFactory; } else { this.options.colorize = colorizrFactory; } this.redraw(false); }, _createTile: function () { var tile = L.TileLayer.prototype._createTile.call(this); tile.crossOrigin = "Anonymous"; return tile; }, _colorize: function (img) { if (img.getAttribute('data-colorized')) { img.hidden = false; return; }else { img.hidden = true; } var _img = img; var img = new Image(); img.crossOrigin = 'Anonymous'; img.src = _img.src; var _this = this; img.onload = function () { var canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.height; var ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0); var imgd = ctx.getImageData(0, 0, canvas.width, canvas.height); var pix = imgd.data; for (var i = 0, n = pix.length; i < n; i += 4) { var pixel = _this.options.colorize({r: pix[i], g: pix[i + 1], b: pix[i + 2], a: pix[i + 3]}); if (!!!pixel || pixel !== Object(pixel) || Object.prototype.toString.call(pixel) === '[object Array]') { if (i === 0) { throw 'The colorize option should return an object with at least one of "r", "g", "b", or "a" properties.'; } } else { if (pixel.hasOwnProperty('r') && typeof pixel.r === 'number') { pix[i] = pixel.r; } if (pixel.hasOwnProperty('g')) { pix[i + 1] = pixel.g; } if (pixel.hasOwnProperty('b')) { pix[i + 2] = pixel.b; } if (pixel.hasOwnProperty('a')) { pix[i + 3] = pixel.a; } } } ctx.putImageData(imgd, 0, 0); _img.setAttribute('data-colorized', true); _img.src = canvas.toDataURL(); }; } }); (function (factory, window) { // define an AMD module that relies on 'leaflet' if (typeof define === 'function' && define.amd) { define(['leaflet'], factory); // define a Common JS module that relies on 'leaflet' } else if (typeof exports === 'object') { module.exports = factory(require('leaflet')); } // attach your plugin to the global 'L' variable if (typeof window !== 'undefined' && window.L) { window.L.tileLayer.colorizr = factory(L); } }(function (L) { return function (url, options) { return new Colorizr(url, options); }; }, window)); })()
用上面的代码直接顶替掉下面这个js插件中的所有代码
以下是使用的方式:
var map = L.map("map", { center: [34.694, 113.587], renderer: L.svg(), zoom: 16, zoomControl: false, // + -号放大缩小 attributionControl: false // 右下角leaflet.js图标 }); // http://192.168.0.105:9090/img/{z}/{x}/{y}.png // 这个是瓦片地图的地址 L.tileLayer.colorizr("http://localhost:9090/img/{z}/{x}/{y}.png", { maxZoom: 18, minZoom: 3, colorize: function (pixel) { // 这个方法用来调整所有的图片上的rgb值,pixel是图片原有的rgb值 pixel.r += 13; pixel.g += 17; pixel.b += 90; return pixel; } }).addTo(map);
需要注意的是,可以配合着给图片加滤镜来做:
.leaflet-zoom-animated img { -webkit-filter: invert(50%) grayscale(0) saturate(0.5) brightness(1.6) opacity(1) hue-rotate(334deg) sepia(10%) !important; -ms-filter: invert(1) grayscale(0) saturate(0.5) brightness(1.6) opacity(1) hue-rotate(334deg) sepia(10%) !important; -moz-filter: invert(1) grayscale(0) saturate(0.5) brightness(1.6) opacity(1) hue-rotate(334deg) sepia(10%) !important; filter: invert(1) grayscale(0) saturate(0.5) brightness(1.6) opacity(1) hue-rotate(334deg) sepia(1%) !important; }
通过修改colorize的返回值就可以实现修改地图的样式了。
总结下实现思路: 这种方法主要是通过拦截地图瓦片数据,然后通过canvas(本人后端,不是太懂,反正这东西能操作图片)操作图片来修改图片的rgb值,从而达到修改地图样式的目的。
最后,感谢下友好的国际友人(虽然没能帮到我),嘻嘻。
可以看看我们有趣的聊天记录
最后的最后,给大家附上一个我自己基于leaflet。js实现的离线地图服务器(下载与部署一体)
总结
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 《庄心妍 实力唱将 发烧音乐精选集》[WAV+CUE][380MB]
- [音展纪念碟]2006年《TAA台湾第十六届国际HI-ENDHI-FI音响展》2cd[WAV]
- 中国音乐地图之听见西藏山歌牧歌酒歌2020[WAV分轨]
- 王宏伟2017-永远的红飘带[太平洋影音][WAV+CUE]
- 费翔.1997-NOW现在【第一中国】【WAV+CUE】
- 新格合唱团.1981-我唱你和2辑(滚石新格民歌系列)【新格】【WAV+CUE】
- 陈柏宇.2011-QUINQUENNIUM【SONY】【WAV+CUE】
- 雨果唱片-《金唛系列-蔷薇依韵琼瑶》WAV
- 陈百强《凝望(2012华纳LPCD45限量版)[DMI]》[WAV整轨]
- 模拟之声慢刻CD《徐小凤45周年》[德国母带][低速原抓WAV+CUE]
- 《庄心妍 实力唱将 发烧音乐精选集》[WAV+CUE][380MB]
- 《王菲 单曲合集》[FlAC/分轨][520MB]
- 《费玉清 原味再现 水长流》[WAV+CUE][430MB]
- 群星.1992-畅销榜老歌金曲10CD【风格】【WAV+CUE】
- 孙悦.2024-时光音乐会【金蜂】【WAV+CUE】