對於各種類型的埋點來說,曝光埋點往往最為複雜、需要用到的技術也最全面、如果實現方式不合理可能造成的影響也最大,因此本文將重點介紹曝光埋點尤其是長列表(或滾動視圖)內元素曝光埋點的實現思路及避坑技巧 ...
在地圖開發中使用自定義圖標(icon)在地圖上表達專題信息十分常見
leaflet中常使用L.marker添加圖標L.icon,非常方便
給定坐標將圖標固定在地圖中的某個位置,由於圖標是有具體大小,並且大小固定不變,在縮放過程中有明顯感覺隨著地圖比例尺縮小,圖標會有一定的偏移
這篇文章主要介紹使用L.icon的iconAnchor屬性解決自定義圖標偏移問題
1 問題復現
上代碼 (後面有完整代碼)
<script>
// 高德衛星影像
const layerC = L.layerGroup([
L.tileLayer('https://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', {
maxZoom: 18,
maxNativeZoom: 16,
minZoom: 3,
attribution: '高德地圖 AutoNavi.com',
subdomains: '1234'
})
])
var map = L.map('map', {attributionControl: false, layers: [layerC]}).setView([29.324720, 112.494506], 13);
const defaultLatlng = [29.324720, 112.494506]
// 添加圓形 顯示定位點
L.circle(defaultLatlng, {radius: 100, color: 'red'}).addTo(map)
// 預設圖標
L.marker(defaultLatlng).addTo(map)
const iconLatlng = [29.31080, 112.50291]
// 自定義圖標
const icon = L.icon({
iconUrl: './船.png',
iconSize: [37, 53], // 設置圖片大小 寬度50.高度100
})
L.circle(iconLatlng, {radius: 100, color: 'red'}).addTo(map)
L.marker(iconLatlng, {icon: icon}).addTo(map)
</script>
使用紅色小圓圈展示圖標的定位點
使用預設圖標,圖標的下方在紅色圓圈中心
使用自定義圖標,最開始圖標直接擋住了紅色圓圈,放大後慢慢的圖標顯示在紅色圓圈裡面,在縮放的過程中自定義圖標的最下方有明顯的偏移(底部指向的位置一直在變)
2 解決方案
探究是什麼導致預設圖標和自定義圖標的區別
leaflet沒有開啟canvas繪製,圖標都是dom元素疊加在底圖上
查看dom元素的css樣式
從圖標樣式中可以看出,圖標使用了margin屬性來實現圖標位置的調整
與預設圖標相比,自定義圖標的margin-top只是height的一半
使用iconAnchor屬性調整一下
const icon = L.icon({
iconUrl: './採砂船正常.png',
iconSize: [37, 53], // 設置圖片大小 寬度50.高度100
iconAnchor: [18.5, 53]
})
自定義圖標縮放的效果沒有偏移的感覺了
完整代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"/>
<!-- Make sure you put this AFTER Leaflet's CSS -->
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="map" style="height: 500px; width: 500px"></div>
<script>
// 高德衛星
const layerC = L.layerGroup([
L.tileLayer('https://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', {
maxZoom: 18,
maxNativeZoom: 16,
minZoom: 3,
attribution: '高德地圖 AutoNavi.com',
subdomains: '1234'
})
])
var map = L.map('map', {attributionControl: false, layers: [layerC]}).setView([29.324720, 112.494506], 13);
const defaultLatlng = [29.324720, 112.494506]
// 添加圓形 顯示定位點
L.circle(defaultLatlng, {radius: 100, color: 'red'}).addTo(map)
// 預設圖標
L.marker(defaultLatlng).addTo(map)
const iconLatlng = [29.31080, 112.50291]
// 自定義圖標
const icon = L.icon({
iconUrl: './船.png',
iconSize: [37, 53], // 設置圖片大小 寬度50.高度100
iconAnchor: [18.5, 53]
})
L.circle(iconLatlng, {radius: 100, color: 'red'}).addTo(map)
L.marker(iconLatlng, {icon: icon}).addTo(map)
// map.on('click', e => {
// console.log(e.latlng)
// })
</script>
</body>
</html>
3 結論
出現這個偏移的感覺主要是由數學坐標系和屏幕坐標的區別導致的。
在數學坐標系中,中心是原點,向上是y軸正方向,所以我們常將一個圖標的底部作為這個圖標的定位點
但在屏幕坐標系,是以左上角作為坐標原點,右方向作為x軸正方向,下方向作為y軸正方向
在屏幕坐標系中,圖標左上角固定不變,縮放過程中,底部指向的位置一直在變,給人感覺就是圖標在慢慢偏移
使用marker預設圖標x和y會自動偏移,使用自定義圖標需要手動偏移
iconAnchor參數是反符號偏移 [18.5, 53] 對應的樣式是margin-left: -18.5 和 margin-top: -53