精品课程网站的设计与建设要求,做网站公司三年财务预算表,有没有外国人做发明的网站,自己想做一个网站因项目需要#xff0c;在uniapp中集成使用腾讯地图#xff0c;为了方便维护#xff0c;希望通过一套代码实现H5和APP同时可用。H5显示相对简单#xff0c;APP端比较麻烦#xff0c;记录下实现过程
一、集成步骤
1.使用 renderjs
script标签使用renderjs#xff0c;因为… 因项目需要在uniapp中集成使用腾讯地图为了方便维护希望通过一套代码实现H5和APP同时可用。H5显示相对简单APP端比较麻烦记录下实现过程
一、集成步骤
1.使用 renderjs
script标签使用renderjs因为JavaScript Api需要调用DOM对象APP需要使用renderjs技术保证script运行在webview环境才能调用DOM对象。
script langrenderjs moduletest
/script
2.引用地图script 导入腾讯地图JS脚本因为腾讯地图js不是按照uniapp格式编写所以不能直接import导入需要包装成一个js插件使用 Promisejs加载成功调用resolvejs加载失败调用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 langrenderjs moduletestimport loadJs from ../../common/loadJs.jsexport default {data() {return {}},mounted(){console.log(renderjs初始化完毕)loadJs(https://map.qq.com/api/gljs?v1.expkeyOB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77).then((){// 加载成功进行后续操作})},methods: {}}
/script
3.修改js兼容uniapp
下载腾讯官网的例子改造成uniapp兼容的格式。有两种方式
方式一
将官网例子中 script 封装成一个个的function定义在 vue文件的 methods 中这样就可以直接调用。
方式二
将官网例子中 script 代码全部拷贝到一个js文件中再把需要调用的 function 通过 export 关键字导出在vue文件中进行 import 调用。
4.修改监听事件
腾讯官网例子都是web端的点击事件都是clickH5端运行需要改成touchend否则点击无响应
Web端
svg.addEventListener(click, this.onClick); web端用click事件
H5端
svg.addEventListener(touchend, this.onClick); // H5端用touchend事件 二、示例
腾讯官网例子
以自定义覆盖物 - DOMOverlay 为例实操下 !DOCTYPE html
html langenheadmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0meta http-equivX-UA-Compatible contentieedgetitleDOMOverlay/title
/head
script charsetutf-8 srchttps://map.qq.com/api/gljs?librariestoolsv1.expkeyOB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77/script
style typetext/csshtml,body {height: 100%;margin: 0px;padding: 0px;}#container {width: 100%;height: 100%;}
/stylebody onloadinitMap()div idcontainer/divscriptvar SVG_NS http://www.w3.org/2000/svg;// 自定义环状饼图 - 继承DOMOverlayfunction 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;/scriptscript typetext/javascriptvar 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?v1.expkeyOB4BZ-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
templateview idmapContainer styleheight: 100%; clicklog/view
/templatescriptexport default {data() {return {}},mounted() {}}
/scriptscript langrenderjs moduletestimport loadJs from ../../common/loadJs.js// 导入适配后的 DOMOverlay.jsimport {initMap} from ../../common/DOMOverlay.jsexport default {data() {return {}},mounted(){console.log(mounted) loadJs(https://map.qq.com/api/gljs?v1.expkeyOB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77).then((){// 调用初始化地图方法initMap()})},methods: {}, created() {}}
/scriptstyle/style三、适配效果
APP运行效果图与官网一致