使用leaflet仿原神提瓦特大地图制作日记



参考页面:原神-观测枢-提瓦特大地图

技术栈:vue,vue2-leaflet



最新效果图 2021.04
戳我↑→↓进入项目git地址,期待反馈吖ヾ(ヾ)
在这里插入图片描述



以下正文:

项目初体验:学习并熟悉leaflet(maker和popup)

在这里插入图片描述

  • 目标是还原提瓦特大地图!虽然当前进度只有0.01%… T^T



leaflet的学习(L-control-zoom)和优化(marker,popup)

2021.03.02

  • leaflet比例尺组件:l-control-zoom,位置属性position=“bottomright”,下一个目标!修改比例尺样式!(完成打卡)

  • 修改了marker的icon

  • 修改了popup里的内容,感觉已经把es6的模版字符串用的炉火纯青有没有,里面遇到了一个如何在拼接html的函数里传字符串,传对象的问题(应该有更好的办法拿html而不是手动拼接吧。希望以后能优化出来

setText(item) {
      let str = ''
      str = (item.isMark ? '取消' : '')
      let classStr = ''
      classStr = (item.isMark ? 'map-popup__switch--marked' : 'map-popup__switch--unmarked')
      const expStr = item.exp ? `<div class="map-popup__exp"><label>获取:</label><div><p>` + item.exp + `</p></div></div>` : ''
      const descStr = item.desc ? `<div class="map-popup__desc"><p><img src="` + this.baseUrl + item.desc + `"></p></div>` : ''
      const contentStr = (item.desc || item.exp) ? `<div class="map-popup__content">${expStr}${descStr}</div>` : ''
      const htmlStr =
          `<div class="map-popup">
            <span class="map-popup__name-link"><label>名称:</label>${item.name}</span>
            <div class="map-popup__type"><label>类型:</label>${item.type}</div>
            ${contentStr}
            <div class="map-popup__switch ${classStr}" οnclick=markPoint(` + JSON.stringify(item) + `)>${str}标记</div>
          </div>`
      return htmlStr
    }



左侧菜单中panel和tab的切换

细化左侧菜单

  • 细化左侧菜单, 主要是panel(观测者标点、我的标点)和tab(海灯节、全地图…)的联动与切换,源代码是通过css样式来实现的(visible和active)



实现切片地图和图片地图(l-tile-layer和l-image-overlay)

在这里插入图片描述

  • 走了不少弯路=皿=,还好最后写出来了,有几个注意点如下

  • 注意点①: marker偏移,解决方案→leaflet添加marker出现偏移,修正方法-icon

  • 注意点②: 自定义瓦片地图接口,手动修改了了leaflet下的leaflet-src.js(瞎瘠薄改 )用以适配原神地图接口入参

//原方法
getTileUrl: function (coords) {
  		var data = {//这些var,是leaflet下的原代码,不是我写的> <!!!
  			r: retina ? '@2x' : '',
  			s: this._getSubdomain(coords),
  			x: coords.x,
  			y: coords.y,
  			z: this._getZoomForUrl()
  		};
  		if (this._map && !this._map.options.crs.infinite) {
  			var invertedY = this._globalTileRange.max.y - coords.y;
  			if (this.options.tms) {
  				data['y'] = invertedY;
  			}
  			data['-y'] = invertedY;
  		}
  		return template(this._url, extend(data, this.options)); 
  	},
//改写方法
getTileUrl: function (coords) {
  		var data = {
  			r: retina ? '@2x' : '',
  			s: this._getSubdomain(coords),
  			x: coords.x,
  			y: coords.y,
  			z: this._getZoomForUrl()
  		};
  		if (this._map && !this._map.options.crs.infinite) {
  			var invertedY = this._globalTileRange.max.y - coords.y;
  			if (this.options.tms) {
  				data['y'] = invertedY;
  			}
  			data['-y'] = invertedY;
  		}
  		// catcat
  		const base='https://uploadstatic.mihoyo.com/ys-obc/2021/02/24/76892539/8b089185befd5f9deec76de5fd40f225_8511148262888359032.jpeg?x-oss-process=image/resize,'
		const sizeType={
  			4:328,
  			7:287,
			13:266,//16张(0-798,798/266=3)
			25:256,
			50:256,
			100:256,
		}
  		const bigType={
  			1:4,
			2:7,
			3:13,
			4:25,
			5:50,
			6:100
		}
  		const size=sizeType[bigType[data.z]]
		const big=bigType[data.z]
		function catcat(x,y,z){  //if逻辑优化
  			let b=Math.pow(2,z-1)-1
			return (x>b||y>b||x<0||y<0)
		}
		if(catcat(data.x,data.y,data.z)){
			return ''
		}
		// if(data.x<0||data.y<0){
		// 	return ''
		// }
		// if(data.z===1&&(data.x>0||data.y>0)){//11=1  2^0
		// 	return ''
		// }
		// if(data.z===2&&(data.x>1||data.y>1)){//22=4 2^1
		// 	return ''
		// }
		// if(data.z===3&&(data.x>3||data.y>3)){//44=16 2^2
		// 	return ''
		// }
		// if(data.z===4&&(data.x>7||data.y>7)){//88=64 2^3
		// 	return ''
		// }
		// if(data.z===5&&(data.x>15||data.y>15)){//1616=256 2^4
		// 	return ''
		// }
		// if(data.z===6&&(data.x>31||data.y>31)){//3232=1024 2^5
		// 	return ''
		// }
  		return `${base}p_${big}/crop,x_${data.x*size},y_${data.y*size},w_${size},h_${size}`
		  // const i = Math.ceil(Math.random() * 4)
		  // return 'http://placekitten.com/256/256?image=' + i
  	},

使用Leaflet.zoomslider插件自定义缩放控件样式

插件的git地址:Leaflet.zoomslider
还是有改它代码,就,不能一步到位的感觉。
①改了leaflet.zoomslider下的L.Control.Zoomslider.js的stepHeight

		var Zoomslider = L.Control.extend({
			options: {
				position: 'topleft',
				// Height of zoom-slider.png in px
				//stepHeight: 8,//原生
				stepHeight: 24,//改写
				// Height of the knob div in px (including border)
				knobHeight: 6,
				styleNS: 'leaflet-control-zoomslider'
			},

②改了vue2-leaflet下的LControlZoom.js的mapObject的赋值

 //catcat
    // this.mapObject = control.zoom(options); //原生
    this.mapObject = control.zoomslider(options);//改写

使用方法是在npm install 这个插件之后,在main.js引入

import 'leaflet.zzoomslider'
import 'leaflet.zoomslider/src/L.Control.Zoomslider.css'

这个样式可以自定义重写,具体的不贴了,有更新在git上。
最终的实现效果:(图一是原生,图二是插件css,图三是自定义重写后的样式)
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值