<template>
<div class="hello">
<div id="map" style="width: 100%; height: 100%"></div>
<div class="layerList">
<ul
@dragstart="dragstart($event, index)"
@dragenter="dragenter($event, index)"
@dragend="dragend($event, index)"
draggable="true"
v-for="(item, index) in list"
:key="item.label"
class="list-item"
>
<div class="layerLabel">
{
{ item.label }}
</div>
</ul>
</div>
</div>
</template>
<script>
export default {
name: "Map",
data() {
return {
list: [
{
id: "5",
url: "url5",
isShow: true,
label: "2016-10-05",
},
{
id: "4",
url: "url4",
isShow: true,
label: "2016-10-04",
},
{
id: "3",
url: "url3",
isShow: true,
label: "2016-10-03",
},
{
id: "2",
url: "url2",
isShow: true,
label: "2016-10-02",
},
{
id: "1",
url: "url1",
isShow: true,
label: "2016-10-01",
},
],
// 源对象的下标
dragIndex: "",
// 目标对象的下标
enterIndex: "",
timeout: null,
startY: 0,
scrollTop: 0,
};
},
methods: {
initmap() {
mapboxgl.accessToken =
"mapbox-token";
let initMap = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mapbox/streets-v11",
zoom: 3, //缩放层级
center: [108.420679, 36.772537], //进入后展现的中心点
});
return initMap;
},
dragstart(e, index) {
this.dragIndex = index;
this.startY = e.offsetY;
document.getElementsByClassName("list-item")[
index
].style.backgroundColor = "rgb(120 145 255)";
},
dragenter(e, index) {
e.preventDefault();
if (this.timeout !== null) {
clearTimeout(this.timeout);
}
// 拖拽事件的防抖
this.timeout = setTimeout(() => {
if (this.dragIndex !== index) {
const source = this.list[this.dragIndex];
this.list.splice(this.dragIndex, 1);
this.list.splice(index, 0, source);
// 排序变化后目标对象的索引变成源对象的索引
this.dragIndex = index;
let parent = document.querySelector(".layerList");
let limitY = parent.scrollHeight - parent.clientHeight;
let offsetY = e.offsetY - this.startY;
this.scrollTop = this.scrollTop - offsetY;
if (this.scrollTop >= limitY) {
// 当滑块移动到底端时
this.scrollTop = limitY;
} else if (this.scrollTop <= 0) {
// 当滑块移动到顶端时
this.scrollTop = 0;
}
// 将计算后的距离赋值给滚动条
parent.scrollTop = this.scrollTop;
}
}, 0);
},
dragend(e, index) {
this.enterIndex = index;
document.getElementsByClassName("list-item")[
index
].style.backgroundColor = "";
let beforeId;
if (index > 0) {
beforeId = this.list[index - 1].id;
} else {
let arr = map.getStyle().layers;
let newindex = arr.findIndex((value) => {
return value.id == this.list[index + 1].id;
});
if (newindex >= 0) {
if (newindex + 1 < map.getStyle().layers.length) {
beforeId = arr[newindex + 1].id;
} else {
beforeId = "";
}
}
}
map.moveLayer(this.list[index].id, beforeId);
},
getList() {
setTimeout(() => {
for (var i = this.list.length - 1; i >= 0; i--) {
let item = this.list[i];
this.addImg(item.id, item.url, item.isShow);
}
});
},
addImg(id, url, isShow) {
if (isShow) {
map.addLayer({
id: id,
type: "raster",
source: {
type: "raster",
tiles: [url],
tileSize: 256,
},
});
} else {
if (map.getLayer(id)) {
map.removeLayer(id);
}
if (map.getSource(id)) {
map.removeSource(id);
}
}
},
},
mounted() {
window.map = this.initmap();
map.on("load", () => {
this.getList();
});
},
};
</script>
<style scoped>
.hello {
position: relative;
width: 100%;
height: 100%;
}
.layerList {
max-height: calc(100vh - 217px);
margin: 10px;
overflow: auto;
position: absolute;
top: 0;
background: #656db8;
width: 350px;
padding: 11px;
}
.list-item {
transition: transform 0.3s;
cursor: move;
width: 100%;
border: 1px solid #544ec8;
border-radius: 4px;
color: #fff;
margin-bottom: 6px;
padding: 8px;
background: #110c8063;
display: flex;
}
</style>
実装のアイデア
まずリストを取得し、最初にトラバースしてレイヤーをロードします
dragstart、dragenter、dragend メソッドを使用して ID を取得します。
ドラッグエンター メソッドは、移動中に彼のスタイルを実装します。