uniapp腾讯地图JavaScript Api,H5端和原生APP端可用

        因项目需要,在uniapp中集成使用腾讯地图,为了方便维护,希望通过一套代码实现H5和APP同时可用。H5显示相对简单,APP端比较麻烦,记录下实现过程

一、集成步骤

1.使用 renderjs

script标签使用renderjs,因为JavaScript Api需要调用DOM对象,APP需要使用renderjs技术,保证script运行在webview环境,才能调用DOM对象。

<script lang="renderjs" module="test">
</script>

2.引用地图script


导入腾讯地图JS脚本,因为腾讯地图js不是按照uniapp格式编写,所以不能直接import导入,需要包装成一个js插件,使用 Promise,js加载成功,调用resolve,js加载失败,调用reject。

创建loadJs.js 文件

function loadJs(src) {
  return new Promise((resolve,reject)=>{
    let script = document.createElement('script');
    script.type = "text/javascript";
    script.src= src;
    document.body.appendChild(script);
      
    script.onload = ()=>{
      resolve();
    }
    script.onerror = ()=>{
      reject();
    }
  }).catch((e) => {})
}
 
export default loadJs


在页面中使用

<script lang="renderjs" module="test">
    import loadJs from "../../common/loadJs.js"
    
    export default {

        data() {
            return {
                
            }
        },
        mounted(){
            console.log('renderjs初始化完毕')
            loadJs('https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77').then(()=>{
                // 加载成功,进行后续操作
            })
        },
         methods: {
        }
    }
</script>

3.修改js,兼容uniapp

下载腾讯官网的例子,改造成uniapp兼容的格式。有两种方式,

方式一:

将官网例子中 script 封装成一个个的function,定义在 vue文件的 methods 中,这样就可以直接调用。

方式二:

将官网例子中 script 代码全部拷贝到一个js文件中,再把需要调用的 function 通过 export 关键字导出,在vue文件中进行 import 调用。

4.修改监听事件

腾讯官网例子都是web端的,点击事件都是click,H5端运行需要改成touchend,否则点击无响应

Web端

svg.addEventListener('click', this.onClick); web端用click事件

H5端

svg.addEventListener('touchend', this.onClick); // H5端用touchend事件

二、示例

腾讯官网例子

以自定义覆盖物 -> DOMOverlay 为例,实操下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>DOMOverlay</title>
</head>
<script charset="utf-8" src="https://map.qq.com/api/gljs?libraries=tools&v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77"></script>
<style type="text/css">
    html,
    body {
        height: 100%;
        margin: 0px;
        padding: 0px;
    }

    #container {
        width: 100%;
        height: 100%;
    }
</style>

<body onload="initMap()">
	<div id="container"></div>
	<script>
		var SVG_NS = 'http://www.w3.org/2000/svg';
		// 自定义环状饼图 - 继承DOMOverlay
		function Donut(options) {
			TMap.DOMOverlay.call(this, options);
		}

		Donut.prototype = new TMap.DOMOverlay();

		// 初始化
		Donut.prototype.onInit = function(options) {
			this.position = options.position;
			this.data = options.data;
			this.minRadius = options.minRadius || 0;
			this.maxRadius = options.maxRadius || 50;
		};

		// 销毁时需解绑事件监听
		Donut.prototype.onDestroy = function() {
			if (this.onClick) {
				this.dom.removeEventListener(this.onClick);
			}
		};

		// 创建DOM元素,返回一个DOMElement,使用this.dom可以获取到这个元素
		Donut.prototype.createDOM = function() {
			let svg = document.createElementNS(SVG_NS, 'svg');
			svg.setAttribute('version', '1.1');
			svg.setAttribute('baseProfile', 'full');

			let r = this.maxRadius;
			svg.setAttribute('viewBox', [-r, -r, r * 2, r * 2].join(' '));
			svg.setAttribute('width', r * 2);
			svg.setAttribute('height', r * 2);
			svg.style.cssText = 'position:absolute;top:0px;left:0px;';

			let donut = createDonut(this.data, this.minRadius, this.maxRadius);
			svg.appendChild(donut);
          
          	// click事件监听
          	this.onClick = () => {
				// DOMOverlay继承自EventEmitter,可以使用emit触发事件
				this.emit('click');
			};
			// pc端注册click事件,移动端注册touchend事件
          	svg.addEventListener('click', this.onClick);
			return svg;
		};

		// 更新DOM元素,在地图移动/缩放后执行
		Donut.prototype.updateDOM = function() {
			if (!this.map) {
				return;
			}

			// 经纬度坐标转容器像素坐标
			let pixel = this.map.projectToContainer(this.position);

			// 使饼图中心点对齐经纬度坐标点
			let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
			let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
			this.dom.style.transform = `translate(${left}, ${top})`;
		};

		// 使用SVG创建环状饼图
		function createDonut(data, minRadius, maxRadius) {
			const colorList = [
				'#7AF4FF',
				'#67D7FF',
				'#52B5FF',
				'#295BFF'
			];
			let sum = data.reduce((prev, curr) => prev + curr, 0);
			let angle = 0;

			let group = document.createElementNS(SVG_NS, "g");
			data.forEach((d, i) => {
				let delta = d / sum * Math.PI * 2;
					color = colorList[i],
					r = maxRadius,
					startAngle = angle,
					endAngle = angle + delta;
				angle += delta;

				// 对每个数据创建一个扇形
				let fanShape = document.createElementNS(SVG_NS, 'path');
				fanShape.setAttribute('style', `fill: ${color};`);
				fanShape.setAttribute('d', [
					'M0 0',
					`L${r * Math.sin(startAngle)} ${-r * Math.cos(startAngle)}`,
					`A${r} ${r} 0 ${delta > Math.PI ? 1 : 0} 1 ${r * Math.sin(endAngle)} ${-r * Math.cos(endAngle)}`,
				].join(' ') + ' z');
				group.appendChild(fanShape);
			});

			// 在中心创建一个圆形
			let circleShape = document.createElementNS(SVG_NS, 'circle');
			circleShape.setAttribute('style', 'fill: #FFFFFF');
			circleShape.setAttribute('cx', 0);
			circleShape.setAttribute('cy', 0);
			circleShape.setAttribute('r', minRadius);
			group.appendChild(circleShape);

			// 绘制文字
			let textShape = document.createElementNS(SVG_NS, 'text');
			textShape.setAttribute('x', 0);
			textShape.setAttribute('y', '0.3em');
			textShape.setAttribute('text-anchor', 'middle');
			textShape.innerHTML = sum;
			group.appendChild(textShape);

			return group;
		}

		window.Donut = Donut;
	</script>
	<script type="text/javascript">
		var map;
        function initMap() {
            // 初始化地图
            map = new TMap.Map("container", {
                zoom:12, // 设置地图缩放级别
                center: new TMap.LatLng(39.984104, 116.307503) // 设置地图中心点坐标
			});

			let donutList = [
				new Donut({
					map,
					position: new TMap.LatLng(39.96030543872138, 116.25809083213608),
					data: [12, 24],
					minRadius: 13,
					maxRadius: 20
				}),
				new Donut({
					map,
					position: new TMap.LatLng(39.9986945980902, 116.33598362780685),
					data: [23, 99, 101, 400],
					minRadius: 25,
					maxRadius: 35
				}),
				new Donut({
					map,
					position: new TMap.LatLng(40.02906301748584, 116.25499991104516),
					data: [18, 41, 50],
					minRadius: 20,
					maxRadius: 28
				})
			];

			donutList.forEach((donut, index) => {
				donut.on('click', () => {
					console.log(`第${index}个环形图被点击,位置为${donut.position}`);
				});
			});
		}
    </script>
</body>

</html>

适配后uniapp代码

主要三个文件 DOMOverlay.js、loadJs.js、map.vue

DOMOverlay.js 

一般来说先把script 全部复制到一个单独js文件,然后直接运行,运气好直接正常使用,运气不好就哪里报错改哪里,DOMOverlay.js文件修改过我都加了注释“适配uniapp修改过的”

var SVG_NS = 'http://www.w3.org/2000/svg';
// 自定义环状饼图 - 继承DOMOverlay
function Donut(options) {
	TMap.DOMOverlay.call(this, options);
}


/** 
 * ----------------适配uniapp修改过的----------------
 * 
 * 因为 TMap 对象依赖于 https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77 
 * 所以要封装一个方法,在加载完依赖脚本后,再运行
 */
function initDonut(){
	Donut.prototype = new TMap.DOMOverlay();
	
	// 初始化
	Donut.prototype.onInit = function(options) {
		this.position = options.position;
		this.data = options.data;
		this.minRadius = options.minRadius || 0;
		this.maxRadius = options.maxRadius || 50;
	};
	
	// 销毁时需解绑事件监听
	Donut.prototype.onDestroy = function() {
		if (this.onClick) {
			this.dom.removeEventListener(this.onClick);
		}
	};
	
	// 创建DOM元素,返回一个DOMElement,使用this.dom可以获取到这个元素
	Donut.prototype.createDOM = function() {
		let svg = document.createElementNS(SVG_NS, 'svg');
		svg.setAttribute('version', '1.1');
		svg.setAttribute('baseProfile', 'full');
	
		let r = this.maxRadius;
		svg.setAttribute('viewBox', [-r, -r, r * 2, r * 2].join(' '));
		svg.setAttribute('width', r * 2);
		svg.setAttribute('height', r * 2);
		svg.style.cssText = 'position:absolute;top:0px;left:0px;';
	
		let donut = createDonut(this.data, this.minRadius, this.maxRadius);
		svg.appendChild(donut);
	  
		// click事件监听
		this.onClick = () => {
			// DOMOverlay继承自EventEmitter,可以使用emit触发事件
			this.emit('click');
		};
		// ----------------适配uniapp修改过的----------------
		// pc端注册click事件,移动端注册touchend事件
		// svg.addEventListener('click', this.onClick); web端用click事件
		svg.addEventListener('touchend', this.onClick); // H5端用touchend事件
		return svg;
	};
	
	// 更新DOM元素,在地图移动/缩放后执行
	Donut.prototype.updateDOM = function() {
		if (!this.map) {
			return;
		}
	
		// 经纬度坐标转容器像素坐标
		let pixel = this.map.projectToContainer(this.position);
	
		// 使饼图中心点对齐经纬度坐标点
		let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
		let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
		this.dom.style.transform = `translate(${left}, ${top})`;
	};
}

// 使用SVG创建环状饼图
function createDonut(data, minRadius, maxRadius) {
	const colorList = [
		'#7AF4FF',
		'#67D7FF',
		'#52B5FF',
		'#295BFF'
	];
	let sum = data.reduce((prev, curr) => prev + curr, 0);
	let angle = 0;

	let group = document.createElementNS(SVG_NS, "g");
	data.forEach((d, i) => {
		let delta = d / sum * Math.PI * 2;
			let color = colorList[i],
			r = maxRadius,
			startAngle = angle,
			endAngle = angle + delta;
		angle += delta;

		// 对每个数据创建一个扇形
		let fanShape = document.createElementNS(SVG_NS, 'path');
		fanShape.setAttribute('style', `fill: ${color};`);
		fanShape.setAttribute('d', [
			'M0 0',
			`L${r * Math.sin(startAngle)} ${-r * Math.cos(startAngle)}`,
			`A${r} ${r} 0 ${delta > Math.PI ? 1 : 0} 1 ${r * Math.sin(endAngle)} ${-r * Math.cos(endAngle)}`,
		].join(' ') + ' z');
		group.appendChild(fanShape);
	});

	// 在中心创建一个圆形
	let circleShape = document.createElementNS(SVG_NS, 'circle');
	circleShape.setAttribute('style', 'fill: #FFFFFF');
	circleShape.setAttribute('cx', 0);
	circleShape.setAttribute('cy', 0);
	circleShape.setAttribute('r', minRadius);
	group.appendChild(circleShape);

	// 绘制文字
	let textShape = document.createElementNS(SVG_NS, 'text');
	textShape.setAttribute('x', 0);
	textShape.setAttribute('y', '0.3em');
	textShape.setAttribute('text-anchor', 'middle');
	textShape.innerHTML = sum;
	group.appendChild(textShape);

	return group;
}

window.Donut = Donut;

var map;
function initMap() {
    // ----------------适配uniapp修改过的----------------
    // 调用封装后的initDount()
	initDonut()
	
	// 初始化地图
	map = new TMap.Map("mapContainer", {
		zoom:12, // 设置地图缩放级别
		center: new TMap.LatLng(39.984104, 116.307503) // 设置地图中心点坐标
	});

	let donutList = [
		new Donut({
			map,
			position: new TMap.LatLng(39.96030543872138, 116.25809083213608),
			data: [12, 24],
			minRadius: 13,
			maxRadius: 20
		}),
		new Donut({
			map,
			position: new TMap.LatLng(39.9986945980902, 116.33598362780685),
			data: [23, 99, 101, 400],
			minRadius: 25,
			maxRadius: 35
		}),
		new Donut({
			map,
			position: new TMap.LatLng(40.02906301748584, 116.25499991104516),
			data: [18, 41, 50],
			minRadius: 20,
			maxRadius: 28
		})
	];

	donutList.forEach((donut, index) => {
		donut.on('click', () => {
			console.log(`第${index}个环形图被点击,位置为${donut.position}`);
			alert(`第${index}个环形图被点击,位置为${donut.position}`)
		});
	});
}

/**
 * ----------------适配uniapp修改过的----------------
 * 导出initMap方法
 */ 
export {
	initMap
}
loadJs.js

用来加载第三方js

function loadJs(src) {
  return new Promise((resolve,reject)=>{
    let script = document.createElement('script');
    script.type = "text/javascript";
    script.src= src;
    document.body.appendChild(script);
      
    script.onload = ()=>{
      resolve();
    }
    script.onerror = ()=>{
      reject();
    }
  }).catch((e) => {})
}
 
export default loadJs
map.vue
<template>
	<view id="mapContainer" style="height: 100%;" @click="log">
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		mounted() {
			
		}
		
	}
</script>

<script lang="renderjs" module="test">
	
	import loadJs from "../../common/loadJs.js"
    // 导入适配后的 DOMOverlay.js
	import {initMap} from "../../common/DOMOverlay.js"
	
	export default {

		data() {
		    return {
				
			}
		},
		mounted(){
			console.log("mounted") 
			loadJs('https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77').then(()=>{
				// 调用初始化地图方法
				initMap()
			})
		},
		 methods: {
		}, 
		created() {
			
		}
	}
</script>

<style>
   
</style>

三、适配效果

APP运行效果图,与官网一致

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

dell戴尔电脑灵越系列Inspiron 15 3520原厂Win11系统中文版/英文版

Dell戴尔笔记本灵越3520原装出厂Windows11系统包&#xff0c;恢复出厂开箱预装OEM系统 链接&#xff1a;https://pan.baidu.com/s/1mMOAnvXz5NCDO_KImHR5gQ?pwd3nvw 提取码&#xff1a;3nvw 原厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、Office办公软件、MyD…

DWG控件Web CAD SDK v15发布,支持注释 2D 绘图

Web CAD SDK为ASP.NET控件&#xff0c;可用于通过Internet、Intranet、Sharepoint、Office 365 及其他在线 HTML5 启用技术查看DWG和其他CAD文件。该产品不要求安装 AutoCAD 或其他第三方应用程序或组件&#xff0c;提供该产品时附带 C# 示例。 我们发布了Web CAD SDK 15 &…

【Unity】如何使用Spine动画

1.下载&#xff0c;选择自己需要的版本下载 下载链接&#xff1a;http://zh.esotericsoftware.com/spine-unity-download 2.下载完&#xff0c;导入Unity里 3.把美术文件拖入Unity里&#xff0c;会自动生成Spine数据 ①_Atlas 文件是texture atlas文件 (.atlas.txt). 它包含对…

国内Twitter账号注册要注意什么?注册多个Twitter账号如何防止被封?

在这个数字化快速发展的时代&#xff0c;Twitter作为一个全球性的社交媒体平台&#xff0c;对于个人品牌塑造乃至跨境电商均有着不可忽视的影响力。然而&#xff0c;在中国大陆地区&#xff0c;对于Twitter账号注册以及如何安全地注册多个Twitter账号这样的话题&#xff0c;往往…

k8s-heml管理 17

Helm是Kubernetes 应用的包管理工具&#xff0c;主要用来管理 Charts&#xff0c;类似Linux系统的 yum。Helm Chart 是用来封装 Kubernetes 原生应用程序的一系列 YAML 文件。可以在你部署应用的时候自定义应用程序的一些 Metadata&#xff0c;以便于应用程序的分发。 对于应用…

同一个包下 golang run时报undefined

问题描述 今天在运行一个项目&#xff0c;一个包下有两个文件&#xff0c;分别是main.go和route&#xff0c;main函数在main.go文件中&#xff0c;main引用了route.go中的两个函数&#xff0c;SetupRoutes和SetupAdminRoutes go build 编译后&#xff0c;直接运行&#xff0c…

【DDD】学习笔记-发布者—订阅者模式

在领域设计模型中引入了领域事件&#xff0c;并不意味着就采用了领域事件建模范式&#xff0c;此时的领域事件仅仅作为一种架构或设计模式而已&#xff0c;属于领域设计模型的设计要素。在领域设计建模阶段&#xff0c;如何选择和设计领域事件&#xff0c;存在不同的模式&#…

连接查询(学习笔记)

通过对DQL的学习&#xff0c;我们可以很轻松的从一张数据表中查询出需要的数据&#xff1b;在企业的应用开发中&#xff0c;我们经常需要从多张表中查询数据&#xff08;例如&#xff1a;我们查询学生信息的时候需要同时查询学生的班级信息&#xff09;&#xff0c;可以通过连接…

伦茨lenze触摸屏维修p500系列P50GAP60300M5H0XXX-02S14315000

Lenze伦茨显示屏维修系列有&#xff1a;EL5800&#xff1b;EL2800&#xff1b;EL9800&#xff1b;EL2500&#xff1b;EL600&#xff1b;P300&#xff1b;P500. 伦茨触摸屏不能触摸维修&#xff1a;触摸屏幕时鼠标箭头无动作&#xff0c;没有发生位置改变。 原因&#xff1a;造…

多维时序 | Matlab实现LSTM-Mutilhead-Attention长短期记忆神经网络融合多头注意力机制多变量时间序列预测模型

多维时序 | Matlab实现LSTM-Mutilhead-Attention长短期记忆神经网络融合多头注意力机制多变量时间序列预测模型 目录 多维时序 | Matlab实现LSTM-Mutilhead-Attention长短期记忆神经网络融合多头注意力机制多变量时间序列预测模型预测效果基本介绍程序设计参考资料 预测效果 基…

ONLYOFFICE 桌面应用程序 v8.0 发布:全新 RTL 界面、本地主题、Moodle 集成等你期待的功能来了!

目录 &#x1f4d8; 前言 &#x1f4df; 一、什么是 ONLYOFFICE 桌面编辑器&#xff1f; &#x1f4df; 二、ONLYOFFICE 8.0版本新增了那些特别的实用模块&#xff1f; 2.1. 可填写的 PDF 表单 2.2. 双向文本 2.3. 电子表格中的新增功能 单变量求解&#xff1a;…

VantUI组件的安装和使用

Vant UI 是一款轻量、可靠的移动端 Vue 组件库&#xff0c;适用于构建高性能的移动端页面。它提供了丰富的组件&#xff0c;如按钮、输入框、弹窗、轮播等&#xff0c;并且具有灵活的配置和扩展性。Vant UI 的设计风格简洁&#xff0c;易于上手&#xff0c;能够满足大部分移动端…

【C++私房菜】面向对象中的简单继承

文章目录 一、 继承基本概念二、派生类对象及派生类向基类的类型转换三、继承中的公有、私有和受保护的访问控制规则四、派生类的作用域五、继承中的静态成员 一、 继承基本概念 通过继承&#xff08;inheritance&#xff09;联系在一起的类构成一种层次关系。通常在层次关系的…

MaxScale实现mysql8读写分离

MaxScale 实验环境 中间件192.168.150.24MaxScale 22.08.4主服务器192.168.150.21mysql 8.0.30从服务器192.168.150.22mysql 8.0.30从服务器192.168.150.23mysql 8.0.30 读写分离基于主从同步 1.先实现数据库主从同步 基于gtid的主从同步配置 主库配置 # tail -3 /etc/my.…

杰发科技AC7801——SRAM 错误检测纠正

0.概述 7801暂时无错误注入&#xff0c;无法直接进中断看错误情况&#xff0c;具体效果后续看7840的带错误注入的测试情况。 1.简介 2.特性 3.功能 4.调试 可以看到在库文件里面有ecc_sram的库。 在官方GPIO代码里面写了点测试代码 成功打开2bit中断 因为没有错误注入&#x…

九州金榜|家庭教育小技巧,孩子好习惯养成记

家庭教育对于孩子的发展至关重要&#xff0c;家长一定要重视孩子在家里的举动&#xff0c;要及时纠正孩子的不足&#xff0c;发展孩子的优良品德和教孩子养成勤俭朴素的的好习惯。九州金榜家庭教育将从以下方面说一下家庭教育中的方法技巧。 一、家长以身作则 家长教育孩子&a…

Stable Diffusion 模型分享:AstrAnime(Astr动画)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五 下载地址 模型介绍 AstrAnime 是一个动漫模型&#xff0c;画风色彩鲜明&#xff0c;擅长绘制漂亮的小姐姐。 条目内容类型大模型…

XG5032HAN (SAW)振荡器)(piezoman压电侠)

XG5032HAN晶体振荡器通过其卓越的低抖动特性&#xff0c;为需要高频率精度和稳定性的电子设备提供了理想的解决方案。无论是在高性能的数据通信、精密测量XG5032HAN都能提供高质量、可靠的性能。同时&#xff0c;宽广的频率范围其25 MHz到250 MHz&#xff0c;小巧的封装5.0 3.…

IntelliJ IDEA 创建Spring Boot 项目整合jdbc详细步骤

IntelliJ IDEA 创建Spring Boot 项目&整合jdbc详细步骤 1、打开 IntelliJ IDEA 软件2、使用 "Spring Initializr" 作为项目类型&#xff0c;新建项目工程3、选择对应的SpringBoot版本和依赖4、Spring Boot 项目的结构5、创建一个TestController&#xff0c;并运行…

C++力扣题目 392--判断子序列 115--不同的子序列 583--两个字符串的删除操作 72--编辑操作

392.判断子序列 力扣题目链接(opens new window) 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串。&#xff08;例如&#xff0c;&quo…