官网效果:
拓展效果:
拓展代码:
<!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>拓展自定义DOM图层-Marker</title>
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=你的地图key"></script>
<style type="text/tailwindcss">
@layer utilities {
.content-auto {
content-visibility: auto;
}
}
</style>
<style>
html,
body {
height: 100%;
margin: 0px;
padding: 0px;
overflow: hidden;
}
#container {
position: relative;
width: 100%;
height: 100%;
}
</style>
</head>
<body onload="initMap()">
<div id="container"></div>
<script>
var SVG_NS = 'http://www.w3.org/2000/svg';
var mapContainer = document.getElementById('container');
// 自定义SVG图层 - 继承DOMOverlay
function SvgMarker(options) {
TMap.DOMOverlay.call(this, options);
}
SvgMarker.prototype = new TMap.DOMOverlay();
// 初始化
SvgMarker.prototype.onInit = function (options) {
this.options = options.options;
this.map = options.map;
};
// 销毁时需解绑事件监听
SvgMarker.prototype.onDestroy = function () {
if (this.onClick) {
this.dom.removeEventListener('click', this.onClick);
}
};
// 创建DOM元素,返回一个DOMElement,使用this.dom可以获取到这个元素
SvgMarker.prototype.createDOM = function () {
var svg = document.createElementNS(SVG_NS, 'svg');
svg.id = 'svgDom';
svg.setAttribute('width', mapContainer.offsetWidth);
svg.setAttribute('height', mapContainer.offsetHeight);
var group = []; // 定义g元素数组
// 遍历传入参数,创建同等数量的svg下元素节点并绑定事件
for (var i = 0; i < this.options.length; i++) {
var createCenter = this.map.projectToContainer(this.options[i].position);
group[i] = document.createElementNS(SVG_NS, 'g');
group[i].setAttribute('filter', 'drop-shadow(0 2px 4px rgba(0,0,0,0.2))');
let element;
// 根据不同id创建不同图形
if (this.options[i].id === 0) {
// 第一个点:三角形
element = document.createElementNS(SVG_NS, 'path');
var size = 15;
var pathData = `M ${
createCenter.x},${
createCenter.y - size}
L ${
createCenter.x - size},${
createCenter.y + size}
L ${
createCenter.x + size},${
createCenter.y + size}
Z`;
element.setAttribute('d', pathData);
element.setAttribute('style', 'fill: #3B82F6; stroke: #FFFFFF; stroke-width: 1; opacity: 0.9;');
} else if (this.options[i].id === 1) {
// 第二个点:正方形
element = document.createElementNS(SVG_NS, 'rect');
var size = 15;
element.setAttribute('x', createCenter.x - size / 2);
element.setAttribute('y', createCenter.y - size / 2);
element.setAttribute('width', size);
element.setAttribute('height', size);
element.setAttribute('rx', '3'); // 圆角
element.setAttribute('style', 'fill: #10B981; stroke: #FFFFFF; stroke-width: 1; opacity: 0.9;');
} else if (this.options[i].id === 2) {
// 第三个点:圆形
element = document.createElementNS(SVG_NS, 'circle');
var size = 15;
element.setAttribute('cx', createCenter.x);
element.setAttribute('cy', createCenter.y);
element.setAttribute('r', size / 2);
element.setAttribute('style', 'fill: #EF4444; stroke: #FFFFFF; stroke-width: 1; opacity: 0.9;');
} else if (this.options[i].id === 3) {
// 第四个点:红旗
group[i].setAttribute('transform', `translate(${
createCenter.x}, ${
createCenter.y})`);
var flag = document.createElementNS(SVG_NS, 'path');
var pathData = `M9.91888 0.0153788C9.89441 0.00405361 9.86688 -0.00118576 9.83926 0.000225193C9.81165 0.00163615 9.785 0.00964392 9.76218 0.0233857C9.74637 0.0329006 8.17039 0.975305 7.12904 0.975398C7.06801 0.975398 7.00951 0.972035 6.95516 0.965389C6.53485 0.914078 6.20324 0.788036 5.85211 0.654627C5.35005 0.463834 4.83087 0.266543 4.01587 0.266543C3.95484 0.266543 3.89207 0.267678 3.82931 0.269946C2.55052 0.315826 1.44197 0.608987 1.11541 0.703095L0.933271 0.530425C0.91217 0.510425 0.884606 0.496586 0.854288 0.490769C0.82397 0.484952 0.792352 0.487438 0.76369 0.497891L0.093715 0.742142C0.0599218 0.754459 0.0323212 0.777083 0.0159852 0.805856C-0.000350688 0.834628 -0.00432421 0.867617 0.00479507 0.898758L3.22656 11.8998C3.23496 11.9285 3.25397 11.9539 3.2806 11.972C3.30723 11.9902 3.33997 12 3.37366 12C3.41341 12 3.45157 11.9863 3.47996 11.9619L4.25462 11.2948C4.2729 11.2791 4.28636 11.2595 4.29375 11.238C4.30115 11.2165 4.30223 11.1936 4.2969 11.1716C4.29007 11.1434 3.61224 8.33824 3.5709 7.70704C3.54896 7.37208 3.6999 7.02774 3.98502 6.76226C4.29303 6.47548 4.91131 6.13362 6.10771 6.13358C6.78315 6.13356 7.4058 6.05634 7.95832 5.90405C8.40374 5.78127 8.80496 5.60974 9.15085 5.39415C9.74734 5.02239 9.97349 4.6479 9.98281 4.63213C9.9941 4.61309 10 4.59194 10 4.57048V0.133495C9.99999 0.109183 9.99243 0.0853355 9.97814 0.0645213C9.96385 0.0437072 9.94335 0.0267159 9.91888 0.0153788Z`;
flag.setAttribute('d', pathData);
flag.setAttribute('style', 'fill: #FF0000; opacity: 0.9;');
group[i].appendChild(flag);
}
if (element) {
group[i].appendChild(element);
}
svg.appendChild(group[i]);
}
return svg;
};
// 更新DOM元素,在地图移动/缩放后执行
SvgMarker.prototype.updateDOM = function () {
if (!this.map) {
return;
}
// 经纬度坐标转容器像素坐标
for (var j = 0; j < this.options.length; j++) {
var pixel = this.map.projectToContainer(this.options[j].position);
var size = 15;
if (this.options[j].id === 0) {
// 更新三角形
var pathData = `M ${
pixel.x},${
pixel.y - size}
L ${
pixel.x - size},${
pixel.y + size}
L ${
pixel.x + size},${
pixel.y + size}
Z`;
this.dom.children[j].getElementsByTagName('path')[0].setAttribute('d', pathData);
} else if (this.options[j].id === 1) {
// 更新正方形
this.dom.children[j].getElementsByTagName('rect')[0].setAttribute('x', pixel.x - size / 2);
this.dom.children[j].getElementsByTagName('rect')[0].setAttribute('y', pixel.y - size / 2);
} else if (this.options[j].id === 2) {
// 更新圆形
this.dom.children[j].getElementsByTagName('circle')[0].setAttribute('cx', pixel.x);
this.dom.children[j].getElementsByTagName('circle')[0].setAttribute('cy', pixel.y);
} else if (this.options[j].id === 3) {
// 更新红旗位置
this.dom.children[j].setAttribute('transform', `translate(${
pixel.x}, ${
pixel.y})`);
}
}
};
window.SvgMarker = SvgMarker;
</script>
<script type="text/javascript">
function initMap() {
// 初始化地图
var map = new TMap.Map('container', {
zoom: 12, // 设置地图缩放级别
center: new TMap.LatLng(39.984104, 116.307503) // 设置地图中心点坐标
});
// 初始化自定义marker类
var marker = new SvgMarker({
map,
options: [
{
position: new TMap.LatLng(39.96030543872138, 116.25809083213608),
id: 0, // 三角形
},
{
position: new TMap.LatLng(39.9986945980902, 116.33598362780685),
id: 1 // 正方形
},
{
position: new TMap.LatLng(40.02906301748584, 116.25499991104516),
id: 2, // 圆形
},
{
position: new TMap.LatLng(39.993194, 116.175488),
id: 3, // 红旗
}
]
});
}
</script>
</body>
</html>
官网代码:
<!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>官网自定义DOM图层-Marker</title>
</head>
<script
charset="utf-8"
src="https://map.qq.com/api/gljs?libraries=tools&v=1.exp&key=你的地图key"
></script>
<style type="text/css">
html,
body {
height: 100%;
margin: 0px;
padding: 0px;
overflow: hidden;
}
#container {
position: relative;
width: 100%;
height: 100%;
}
</style>
<body onload="initMap()">
<div id="container"></div>
<script>
var SVG_NS = 'http://www.w3.org/2000/svg';
var colorList = ['#7AF4FF', '#67D7FF', '#52B5FF', '#295BFF'];
var mapContainer = document.getElementById('container');
// 自定义SVG图层 - 继承DOMOverlay
function SvgMarker(options) {
TMap.DOMOverlay.call(this, options);
}
SvgMarker.prototype = new TMap.DOMOverlay();
// 初始化
SvgMarker.prototype.onInit = function (options) {
this.options = options.options;
this.map = options.map;
};
// 销毁时需解绑事件监听
SvgMarker.prototype.onDestroy = function () {
if (this.onClick) {
this.dom.removeEventListener(this.onClick);
}
};
// 创建DOM元素,返回一个DOMElement,使用this.dom可以获取到这个元素
SvgMarker.prototype.createDOM = function () {
var svg = document.createElementNS(SVG_NS, 'svg');
svg.id = 'svgDom';
svg.setAttribute('width', mapContainer.offsetWidth);
svg.setAttribute('height', mapContainer.offsetHeight);
svg.style.cssText = 'position:absolute;top:0px;left:0px;';
var group = []; // 定义g元素数组
var circleShape = []; // 定义circle元素数组
var textShape = []; // 定义text元素数组
// 遍历传入参数,创建同等数量的svg下元素节点并绑定事件
for (var i = 0; i < this.options.length; i++) {
var createCenter = this.map.projectToContainer(this.options[i].position);
group[i] = document.createElementNS(SVG_NS, 'g');
// 在中心创建一个圆形
circleShape[i] = document.createElementNS(SVG_NS, 'circle');
circleShape[i].setAttribute('style', 'fill: blue;stroke:#FFFFFF;opacity:0.9;');
circleShape[i].setAttribute('cx', createCenter.x);
circleShape[i].setAttribute('cy', createCenter.y);
circleShape[i].setAttribute('r', 20);
group[i].appendChild(circleShape[i]);
// 绘制文字
textShape[i] = document.createElementNS(SVG_NS, 'text');
textShape[i].setAttribute('x', createCenter.x);
textShape[i].setAttribute('y', createCenter.y + 5); // +5是为了让文字向下偏移5像素,使文字居中
textShape[i].setAttribute('text-anchor', 'middle');
textShape[i].setAttribute('fill', '#FFFFFF');
textShape[i].innerHTML = this.options[i].id + 1;
svg.appendChild(group[i]);
group[i].appendChild(textShape[i]);
this.onMouseEnter = function(e) {
// DOMOverlay继承自EventEmitter,可以使用emit触发事件
// 动态修改circle颜色,所以选择传入circle节点
this.emit('mouseenter', e.target.firstChild);
}.bind(this);
this.onMouseLeave = function(e) {
this.emit('mouseleave', e.target.firstChild);
}.bind(this);
group[i].addEventListener('mouseenter', this.onMouseEnter);
group[i].addEventListener('mouseleave', this.onMouseLeave);
}
return svg;
};
// 更新DOM元素,在地图移动/缩放后执行
SvgMarker.prototype.updateDOM = function () {
if (!this.map) {
return;
}
// 经纬度坐标转容器像素坐标
for (var j = 0; j < this.options.length; j++) {
var pixel = this.map.projectToContainer(this.options[j].position);
var updateCenter = this.map.projectToContainer(this.options[j].position);
this.dom.children[j]
.getElementsByTagName('circle')[0]
.setAttribute('cx', updateCenter.x);
this.dom.children[j]
.getElementsByTagName('circle')[0]
.setAttribute('cy', updateCenter.y);
this.dom.children[j]
.getElementsByTagName('text')[0]
.setAttribute('x', updateCenter.x);
this.dom.children[j]
.getElementsByTagName('text')[0]
.setAttribute('y', updateCenter.y + 5);
}
};
window.SvgMarker = SvgMarker;
</script>
<script type="text/javascript">
function initMap() {
// 初始化地图
var map = new TMap.Map('container', {
zoom: 12, // 设置地图缩放级别
center: new TMap.LatLng(39.984104, 116.307503) // 设置地图中心点坐标
});
// 初始化自定义marker类
var marker = new SvgMarker({
map,
options: [
{
position: new TMap.LatLng(39.96030543872138, 116.25809083213608),
id: 0,
},
{
position: new TMap.LatLng(39.9986945980902, 116.33598362780685),
id: 1
},
{
position: new TMap.LatLng(40.02906301748584, 116.25499991104516),
id: 2,
}
]
});
map.res
marker.on('mouseenter', function(e) {
e.setAttribute('style', 'fill: red;stroke:red; opacity:0.9;');
});
marker.on('mouseleave', function(e) {
e.setAttribute('style', 'fill: blue;stroke:#FFFFFF;opacity:0.9;');
});
// 监听地图容器变化,动态修改svg图层大小,防止更新时元素移出svg图区
map.on('resize', function() {
document.getElementById('svgDom').setAttribute('width', mapContainer.offsetWidth);
document.getElementById('svgDom').setAttribute('height', mapContainer.offsetHeight);
})
}
</script>
</body>
</html>
© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END
暂无评论内容