Mapboxgl ドラッグ アンド ドロップでレイヤーの順序を切り替える

<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 を取得します。

ドラッグエンター メソッドは、移動中に彼のスタイルを実装します。

おすすめ

転載: blog.csdn.net/xm_w_xm/article/details/129028143