首页 > 其他分享 >高德地图动态Marker和自定义弹框、交互事件、中心点跳转

高德地图动态Marker和自定义弹框、交互事件、中心点跳转

时间:2023-06-27 19:45:41浏览次数:42  
标签:box 自定义 10px 弹框 5px 跳转 marker shadow 0px

高德地图

vue3 使用

下载 NPM:
npm i @amap/amap-jsapi-loader --save

根据官网提示,VUE3 需要改变监听模式

下载

npm i @vue/reactivity
组件内配置初始化
<script setup>
//开发技术   vue3 pinia  ts
import { ref } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";  //引入地图
import { onMounted } from "vue";
import { shallowRef } from "@vue/reactivity";  //改变监听
let map = shallowRef(null); //设置地图

const initMap = () => {
  AMapLoader.load({
    key: "密钥", // 申请好的Web端开发者Key,首次调用 load 时必填
    version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
    plugins: [""], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
  })						//container容器
    .then((AMap) => {
      map = new AMap.Map("container", {
        //设置地图容器id  container
        viewMode: "3D", //是否为3D地图模式
        zoom: 13,//初始化地图级别
        center: [113.83804, 22.62621], //初始化地图中心点位置
        //mapStyle: "amap://styles/darkblue",  //设置样式
      });
    })
    .catch((e) => {
      console.log(e); //错误打印
    });
};

onMounted(() => {
  initMap();    //调用这个高德地图
});
</script>

<template>
  <div id="container"></div>  //容器
</template>

<style lang="scss" scoped>
#container {   //地图显示设置盒子大小
  width: 100%;
  height: 100%;
}
</style>

Marker 点创建
//抽离创建Marker点
<script>
const initMap = () => {
  AMapLoader.load({
    key: "密钥",
    version: "2.0",
    plugins: [""],
  })
    .then((AMap) => {
      map = new AMap.Map("container", {
        viewMode: "3D",
        zoom: 13,
        center: [113.83804, 22.62621],
      });
      createMarker();//创建Marker点抽离=====================================
    })
    .catch((e) => {
      console.log(e);
    });
};

onMounted(() => {
  initMap();
});
</script>

<script>  //Marker方法抽离
 let markers = ref([  //点位信息后端获取
  {
    carNum: "桂LMM267",
    in: "alert0", //样式
    position: [113.821215, 22.607418],
    zt: "离线",
  },
  {
    carNum: "粤LMM267",
    in: "alert1",
    position: [116.368904, 45.913423],
    zt: "运动",
  },
]);


const createMarker = () => {
  map.clearMap(); // 清除地图覆盖物
  markers.value.forEach(function (marker: any) { //循环创建marker点
    let markerss = new AMap.Marker({
      resizeEnable: true,
      map: map,
      content: `<div class="${marker.in}" style='color: red;'></div>`,
        //content是marker点内容  ${marker.in}动态样式
      position: [marker.position[0], marker.position[1]], //@ts-ignore
        //position配置每个marker点的位置
      offset: new AMap.Pixel(-13, -30),
        //offset配置marker点偏移量
    });

      markerss.setLabel({
      direction: "centre",
      offset: new AMap.Pixel(0, 50), //设置文本标注偏移量
      content: `<div class='info'>${marker.carNum}</div>`, //设置文本标注内容
    });
      //setLabel是marker点底部的提示标签

    markerss.orderno = marker.zt; //属性传值用来动态传弹窗内容
    //鼠标点击marker弹出自定义的信息窗体
    markerss.on("click", openInfo);
    //鼠标经过事件
    markerss.on("mouseover", openInfo); //移入Marker
    markerss.on("mouseout", setnum); //移出Marker 用来做发送请求防抖
    // 第一个参数为空,表明用图上所有覆盖物 setFitview
    // 第二个参数为false, 非立即执行
    // 第三个参数设置上左下右的空白
    markerss.setMap(map); //把点再地图上
    // map.setFitView(null, false, [20, 20, 20, 30]);
  });
};
</script>
//===========注意!! marker样式设置不能 scope样式隔离===========
<style lang="scss">
#container {
  width: 100%;
  height: 100%;
  .amap-marker-label {
    border: 1px solid #ccc;
	//标签的样式官方有文档
    border-radius: 5px;
    // background-color: transparent;
    background-color: #f7f7f7;
  }
  .info {
    color: rgb(97, 97, 197);
  }
  .inputEnd {
    color: #2d7ad6;
  }
}
//下面就是两个不同颜色Marker点的样式
.alert1 {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #ff0000;
  margin: auto 5px;
  animation: animation1 1s infinite;
}
/*高德地图标注动画*/
@keyframes animation1 {
  0% {
    -moz-box-shadow: 0px 0px 10px 5px #ff0000;
    box-shadow: 0px 0px 10px 5px #ff0000;
  }
  50% {
    -moz-box-shadow: 0px 0px 20px 5px #ff0000;
    box-shadow: 0px 0px 20px 5px #ff0000;
  }
  100% {
    -moz-box-shadow: 0px 0px 10px 5px #ff0000;
    box-shadow: 0px 0px 10px 5px #ff0000;
  }
  150% {
    -moz-box-shadow: 0px 0px 50px 5px #ff0000;
    box-shadow: 0px 0px 50px 5px #ff0000;
  }
}

.alert2 {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #00e921;
  margin: auto 5px;
  animation: animation2 1s infinite;
}

@keyframes animation2 {
  0% {
    -moz-box-shadow: 0px 0px 10px 5px #00e921;
    box-shadow: 0px 0px 10px 5px #00e921;
  }
  50% {
    -moz-box-shadow: 0px 0px 20px 5px #00e921;
    box-shadow: 0px 0px 20px 5px #00e921;
  }
  100% {
    -moz-box-shadow: 0px 0px 10px 5px #00e921;
    box-shadow: 0px 0px 10px 5px #00e921;
  }
  150% {
    -moz-box-shadow: 0px 0px 50px 5px #00e921;
    box-shadow: 0px 0px 50px 5px #00e921;
  }
}
.alert0 {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #656565;
  margin: auto 5px;
}
</style>

动态 Marker 点
//在接收到新数据后直接调用抽离的createMarker()
//例  markers 根据WebSocket返回的数据刷新
// var markers: any = ref([]);
// if (window.WebSocket) {
//   var ws = new WebSocket("ws://localhost:8000");

//   ws.onopen = function (e) {
//     console.log("连接服务器成功");
//     ws.send("index");
//   };
//   ws.onclose = function (e) {
//     console.log("服务器关闭");
//   };
//   ws.onerror = function () {
//     console.log("连接出错");
//   };

//   ws.onmessage = function (e) {
//     markers.value.splice(0);
//     let arr: any = JSON.parse(e.data);
//     markers.value.push(...arr);
//     //刷新marker点
//     createMarker();
//   };
// }

弹窗 Marker 点跳转 地理位置逆向解析 infoWindow 自定义信息框 事件交互 完整代码

<script setup lang="ts">
//开发技术   vue3 pinia  ts
import { ref, watch } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader"; //引入地图
import { onMounted } from "vue"; //地图需要挂载在onMounted钩子
import { shallowRef } from "@vue/reactivity"; //改变监听
import axios from "axios"; //单独配置高德地图逆向解析经纬度请求 就直接用原生axios发送了
let showInfo = 0; //控制InfoWindow弹窗防抖 因为鼠标放上Marker点后 一直触发鼠标移入事件 用这个配合鼠标移出事件达到防抖

//用websocket实时推送
//动态数据
// var markers: any = ref([]);
// if (window.WebSocket) {
//   var ws = new WebSocket("ws://localhost:8000");

//   ws.onopen = function (e) {
//     console.log("连接服务器成功");
//     ws.send("index");
//   };
//   ws.onclose = function (e) {
//     console.log("服务器关闭");
//   };
//   ws.onerror = function () {
//     console.log("连接出错");
//   };

//   ws.onmessage = function (e) {
//     markers.value.splice(0);
//     let arr: any = JSON.parse(e.data);
//     markers.value.push(...arr);
//     //动态刷新marker点
//     createMarker();
//   };
// }

//死数据
var markers = ref([
  {
    carNum: "桂LMM267",
    in: "alert0",
    position: [113.821215, 22.607418],
    zt: "离线",
  },
  {
    carNum: "粤LMM267",
    in: "alert1",
    position: [116.368904, 45.913423],
    zt: "运动",
  },
  {
    carNum: "粤LMM267",
    in: "alert2",
    position: [116.305467, 30.807761],
    zt: "静止",
  },
  {
    carNum: "粤LMM267",
    in: "alert0",
    position: [126.205467, 39.907761],
    zt: "静止",
  },
  {
    carNum: "粤LMM267",
    in: "alert1",
    position: [108.878913, 35.210191],
    zt: "静止",
  },
  {
    carNum: "粤LMM997",
    in: "alert1",
    position: [106.205467, 39.907761],
    zt: "静止",
  },
  {
    carNum: "粤KLM267",
    in: "alert0",
    position: [102.706709, 25.047415],
    zt: "静止",
  },
]);

var map: any = shallowRef(null); //设置监听

let positionCn: any = ref(""); //转换后的地址中文
//点归位置
const outMarker = () => {
  //调用归位点
  // 第一个参数为空,表明用图上所有覆盖物 setFitview
  // 第二个参数为false, 非立即执行
  // 第三个参数设置上左下右的空白
  map.setFitView(null, false, [150, 60, 100, 60]);
};

//多个标记点 数据
//0离线,1运动,2静止

//点事件弹窗抽离出来包括移动中心点
//移出事件配合下面的发请求
let setnum = () => {
  num = 0;
};

var openInfo = (e) => {
  showInfo++;

  if (showInfo == 1) {
    let positionCar = e.target._position;
    console.log(e.type);

    console.log("发送了请求");

    //防抖 发请求获取逆向地理位置
    axios
      .get(
        `https://restapi.amap.com/v3/geocode/regeo?key=你的密钥&location=${positionCar[0]},${positionCar[1]}&poitype=地名地址信息&radius=100&extensions=all&batch=false&roadlevel=0`
      )
      .then((res) => {
        positionCn.value = res.data.regeocode.formatted_address;
      });

    //逆向地理查询
    //根据请求逆向编码地址

    //用watch监听 中文地址 因为是异步返回的 所以监听到值改变后 再创建弹窗
    watch(positionCn, () => {
      var info: any = [];
      info.push(
        '<div class=\'input-card content-window-card\'><div><img style="float:left;" src=" https://webapi.amap.com/images/autonavi.png "/></div> '
      );
      info.push('<div  style="padding:7px 0px 0px 0px;" color: red><h4>速度</h4>');
      info.push(
        `<p class='input-item' style='color: red;'>地址:${positionCn.value}</p></div></div>`
      );
      info.push(`<p class='inputEnd' >状态:${e.target.orderno}</p></div></div>`);
      info.push(`<button onclick="getLen()">发送请求</button>`); //点击事件
      //@ts-ignore
      let infoWindow = new AMap.InfoWindow({
        autoMove: true,
        closeWhenClickMap: true,
        content: info.join(""), //使用默认信息窗体框样式,显示信息内容
        //@ts-ignore
        offset: new AMap.Pixel(0, -30),
      });
      //@ts-ignore
      //第二参数表示展示的位置
      infoWindow.open(map, e.target.getPosition());
    });
    // infoWindow.open(map, e.target.getPosition());
    //构建信息窗体中显示的内容
    //如果是点击事件就跳转
  }
  if (e.type === "click") {
    // //中心点跳转
    map.setZoomAndCenter(15, e.target.getPosition());
  }
};
//Marker创建抽离
const createMarker = () => {
  //@ts-ignore
  map.clearMap(); // 清除地图覆盖物
  markers.value.forEach(async function (marker: any) {
    //@ts-ignore
    let markerss = await new AMap.Marker({
      resizeEnable: true,
      map: map,
      content: `<div class="${marker.in}" style='color: red;'></div>`,
      position: [marker.position[0], marker.position[1]], //@ts-ignore
      offset: new AMap.Pixel(-13, -30),
    });
    await markerss.setLabel({
      direction: "centre",
      //@ts-ignore
      offset: new AMap.Pixel(0, 50), //设置文本标注偏移量
      content: `<div class='info'>${marker.carNum}</div>`, //设置文本标注内容
    });

    markerss.orderno = marker.zt; //传值

    //   //   //鼠标点击marker弹出自定义的信息窗体
    markerss.on("click", openInfo);
    //鼠标经过事件
    markerss.on("mouseover", openInfo); //移入Marker
    markerss.on("mouseout", setnum); //移出Marker 用来做发送请求防抖
    // 第一个参数为空,表明用图上所有覆盖物 setFitview
    // 第二个参数为false, 非立即执行
    // 第三个参数设置上左下右的空白
    markerss.setMap(map); //把点再地图上
    // map.setFitView(null, false, [20, 20, 20, 30]);
  });
};
// watch(markers, () => {
//   console.log(1231);

// });

const initMap = () => {
  //@ts-expect-error
  window._AMapSecurityConfig = { securityJsCode: "你的密钥" };
  AMapLoader.load({
    key: "你的密钥", // 申请好的Web端开发者Key,首次调用 load 时必填
    version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
    plugins: ["AMap.Geocoder", "AMap.Geolocation", "AMap.ControlBar"], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
  }) //container容器
    .then((AMap) => {
      map = new AMap.Map("container", {
        //设置地图容器id
        viewMode: "3D", //是否为3D地图模式
        mapStyle: "amap://styles/dd878847b26aa456c92b21c23de177d3",
        zoom: 4.8,
        center: [106.577823, 33.168496],

        //zoom: 8, //初始化地图级别
        //center: [113.83804, 22.62621], //初始化地图中心点位置
        //mapStyle: "amap://styles/darkblue", //设置样式
      });

      //创建Marker点
      createMarker();
    })
    .catch((e) => {
      console.log(e); //错误打印
    });
};

onMounted(() => {
  initMap(); //调用这个高德地图
});
//@ts-ignore
window.getLen = () => {
  //弹窗点击事件调用
  console.log("22222");
};
</script>

<template>
  <div class="all">
    <button onclick="infoClick()"></button>
    <div id="container"></div>
    <button class="btn" @click="outMarker">marker归位</button>
  </div>
</template>

<style lang="scss">
.all {
  position: relative;
  width: 100%;
  height: 100%;
}
#container {
  width: 100%;
  height: 100%;
  .amap-marker-label {
    border: 1px solid #ccc;

    border-radius: 5px;
    // background-color: transparent;
    background-color: #f7f7f7;
  }
  .info {
    color: rgb(97, 97, 197);
  }
  .inputEnd {
    color: #2d7ad6;
  }
}
.btn {
  position: absolute;
  top: 20px;
  z-index: 9999;
  color: red;
}
.alert1 {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #ff0000;
  margin: auto 5px;
  animation: animation1 1s infinite;
}
/*高德地图标注动画*/
@keyframes animation1 {
  0% {
    -moz-box-shadow: 0px 0px 10px 5px #ff0000;
    box-shadow: 0px 0px 10px 5px #ff0000;
  }
  50% {
    -moz-box-shadow: 0px 0px 20px 5px #ff0000;
    box-shadow: 0px 0px 20px 5px #ff0000;
  }
  100% {
    -moz-box-shadow: 0px 0px 10px 5px #ff0000;
    box-shadow: 0px 0px 10px 5px #ff0000;
  }
  150% {
    -moz-box-shadow: 0px 0px 50px 5px #ff0000;
    box-shadow: 0px 0px 50px 5px #ff0000;
  }
}

.alert2 {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #00e921;
  margin: auto 5px;
  animation: animation2 1s infinite;
}

@keyframes animation2 {
  0% {
    -moz-box-shadow: 0px 0px 10px 5px #00e921;
    box-shadow: 0px 0px 10px 5px #00e921;
  }
  50% {
    -moz-box-shadow: 0px 0px 20px 5px #00e921;
    box-shadow: 0px 0px 20px 5px #00e921;
  }
  100% {
    -moz-box-shadow: 0px 0px 10px 5px #00e921;
    box-shadow: 0px 0px 10px 5px #00e921;
  }
  150% {
    -moz-box-shadow: 0px 0px 50px 5px #00e921;
    box-shadow: 0px 0px 50px 5px #00e921;
  }
}
.alert0 {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #656565;
  margin: auto 5px;
}
</style>

标签:box,自定义,10px,弹框,5px,跳转,marker,shadow,0px
From: https://www.cnblogs.com/yitiaogua/p/17509761.html

相关文章

  • Go语言中的自定义函数类型
    函数类型的基本概念在Go语言中,函数类型是一种将函数作为值的数据类型。与其他类型一样,函数类型可以被声明、赋值给变量,作为参数传递和作为返回值返回。通过函数类型,我们可以将函数看作一种可执行的对象,对其进行操作和处理。自定义函数类型的语法在Go语言中,我们可以使用type......
  • elementUI中upload自定义上传行为 http-request属性
    需求是上传一个xlsx后台处理完再返回xlsx流upload请求需要添加responseType:'blob'属性所有要扩展一下若依项目扩展elementUI中upload自定义上传行为http-request属性<el-uploadref="upload1":limit="1"accept=".xlsx,.xls":headers="......
  • 如何高度优化适用于企业自定义的AI (一) 序言
    概述在当前信息时代的背景下,社会对AI的需求在不断增长.AI的快速发展得益于大数据、云计算和计算能力的提升,使得机器学习和深度学习等技术取得了重大突破.AI在图像识别、语音识别、自然语言处理等领域展现出惊人的能力,为企业带来了巨大的商机.然而,通用的AI解决方案无法......
  • 直播开发app,vue防抖 自定义ref实现输入框防抖
    直播开发app,vue防抖自定义ref实现输入框防抖 首先需要把input的双向绑定v-mode拆开为一个value和一个input事件,在事件里注册一个函数debUpdata,debUpdata里获取到input输入内容再赋值给text,这就类似于手写v-mode,代码如下: <template> <divclass="hello">  <inpu......
  • 【HarmonyOS】低代码开发使用module中的自定义组件
     “Module是应用/服务的基本功能单元,包含了源代码、资源文件、第三方库及应用/服务配置文件,每一个Module都可以独立进行编译和运行。一个HarmonyOS应用/服务通常会包含一个或多个Module,因此,可以在工程中创建多个Module,每个Module分为Ability和Library两种类型。”这个是HarmonyOS......
  • Spring REST 接口自定义404不能捕获NoHandlerFoundException问题
    SpringREST接口自定义404以及解决不能捕获NoHandlerFoundException问题  一、自定义404响应内容版本说明:SpringBoot2.0.1.RELEASEREST风格默认PostMan请求的404响应如下:{"timestamp":"2018-06-07T05:23:27.196+0000","status":404,"error":&quo......
  • Android自定义控件
    继承现有控件类publicclassLeftButtonBarextendsLinearLayout{//默认实现的构造函数beginpublicLeftButtonBar(Contextcontext){super(context);}publicLeftButtonBar(Contextcontext,@NullableAttributeSetattrs){supe......
  • 前端Vue自定义加载中loading加载结束end组件 可用于分页展示 页面加载请求
    前端Vue自定义加载中loading加载结束end组件可用于分页展示页面加载请求,请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13219效果图如下:实现代码如下:cc-paging使用方法<!--加载中用法isLoading:是否加载isEnd:是否结束加载--><cc-paging:isLoad......
  • 前端Vue自定义发送短信验证码弹框popup 实现剩余秒数计数 重发短信验证码
    前端Vue自定义发送短信验证码弹框popup实现剩余秒数计数重发短信验证码,请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13207效果图如下:实现代码如下:cc-codeDialog使用方法<!--show:是否显示弹框phone:手机号 autoCountdown:自动时间秒数len:短信......
  • 前端Vue自定义验证码密码登录切换tabs选项卡标签栏标题栏 验证码登录模版 密码登录模
    前端Vue自定义验证码密码登录切换tabs选项卡标签栏标题栏验证码登录模版密码登录模版,请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13221效果图如下:实现代码如下:cc-selectBox使用方法<!--select-arr:选择数组nowindex:当前选择序列@change:切换选择......