js
复制代码
<template>
<div class="index5 w100 h100 white relative">
<canvas
id="myCanvas"
style="display: none; width: 100vw; height: 100vh"
></canvas>
<img
src="./components/img/home.png"
alt=""
class="home pointer"
@click="$router.back()"
/>
<!-- 地图区域 -->
<div id="containerMap" class="w100 h100" ref="htmlImg"></div>
<!-- 左侧菜单 -->
<div
v-show="showMenu"
class="left h80 absolute animate__animated animate__slideInLeft animate__fast"
>
<div class="w100 pdRem-20 h100">
<dv-border-box-8
:color="['rgba(2, 208, 249,.5)', '#0dcff2']"
backgroundColor="rgba(4, 33, 66,.8)"
>
<div class="plrRem-20 ptbRem-10 flex flex-column w100 h100">
<div class="title flex_l mtb-20">
<img src="./components/img/index1-title.png" alt="" />
作战标绘
</div>
<div class="flex flex-wrap w100">
<div
class="item plr-20 text-center mb-20 pointer"
style="width: 50%"
v-for="(item, index) in tab"
:key="index"
>
<!-- ☆☆☆☆☆ 拖拽图片默认会打开窗口预览,换成背景图即可 -->
<!-- <img :src="item.icon" alt="" style="width: 50px" /> -->
<div
draggable="true"
@dragstart="onDragStart"
@dragend="onDragEnd"
:data-index="index"
class="img-bg"
:style="{
backgroundImage: `url(${item.icon})`,
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center',
backgroundSize: 'cover',
backgroundAttachment: 'local',
}"
></div>
<div class="mt-4">{{ item.text }}</div>
</div>
</div>
<img
src="./components/img/index5-btn4.png"
alt=""
style="width: 140px; margin: 60px auto 20px"
@click="issueImg"
class="pointer"
/>
</div>
</dv-border-box-8>
</div>
</div>
<!-- 右下控制 -->
<div
v-show="showMenu && showEdit"
class="right absolute animate__animated animate__slideInLeft animate__fast pdRem-20"
>
<div class="w100 h100 editBox ptRem-14 pbRem-10 plRem-10 prRem-20">
<div class="plrRem-20 ptbRem-10 flex flex-column w100 h100 editContent">
<div class="title flex_l mtb-10">
<img src="./components/img/index1-title.png" alt="" />
标绘属性
</div>
<div class="plrRem-20 mbRem-20 flex flex-column">
<div class="flex1">
<div style="width: 60px; font-size: 0.2rem">缩放:</div>
<div class="flex-1">
<el-slider
:max="10"
:min="0.5"
:step="0.5"
v-model="scale"
@change="editMarker"
></el-slider>
</div>
</div>
<div class="flex1">
<div style="width: 60px; font-size: 0.2rem">角度:</div>
<div class="flex-1">
<el-slider
:max="360"
:step="5"
v-model="rotate"
@change="editMarker"
></el-slider>
</div>
</div>
</div>
<div class="w100 center mb-20">
<!-- <img
src="./components/img/index5-btn1.png"
alt=""
style="width: 140px"
@click="saveImg"
class="pointer"
v-if="isSave"
/> -->
<img
src="./components/img/index5-btn3.png"
alt=""
style="width: 120px"
@click="removeMarker"
class="pointer"
/>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import html2canvas from "html2canvas";
import "./components/js/flexible.js";
import {
getPoliceDetailApi,
uploadHtmlImg,
dispatchHtmlImg,
} from "./components/js/api";
import AMapLoader from "@amap/amap-jsapi-loader";
import icon1 from "./components/img/index5-1.png";
import icon2 from "./components/img/index5-2.png";
import icon3 from "./components/img/index5-3.png";
import icon4 from "./components/img/index5-4.png";
import icon5 from "./components/img/index5-5.png";
import icon6 from "./components/img/index5-6.png";
import icon7 from "./components/img/index5-7.png";
import icon8 from "./components/img/index5-8.png";
import icon9 from "./components/img/index5-9.png";
//秘钥
window._AMapSecurityConfig = {
securityJsCode: "3e9a9aeb435372339552fc215f8d0918",
};
export default {
data() {
return {
position: [],
policeId: "",
map: null,
showMenu: true,
tab: [
{
id: 1,
icon: icon1,
text: "消防车",
},
{
id: 2,
icon: icon2,
text: "消防员",
},
{
id: 3,
icon: icon3,
text: "水管",
},
{
id: 4,
icon: icon4,
text: "进攻方向",
},
{
id: 5,
icon: icon5,
text: "消防栓",
},
{
id: 6,
icon: icon6,
text: "危化品",
},
{
id: 7,
icon: icon7,
text: "风向",
},
{
id: 8,
icon: icon8,
text: "指北矢标",
},
],
list: [], //地图上所有的marker
draggingEnded: false,
index: null, //当前拖动的索引-对应左侧菜单
showEdit: false, //是否显示编辑
item: {}, //当前编辑的marker
// 编辑
scale: 1, //缩放
rotate: 0, //旋转角度
//保存
baseUrl: process.env.VUE_APP_BASE_API,
isSave: false,
};
},
mounted() {
this.position = this.$route.query.position.split(",");
this.policeId = this.$route.query.id;
this.initAMap();
},
beforeDestroy() {
this.map.destroy();
},
methods: {
// -----------地图--------------
initAMap() {
AMapLoader.load({
key: "130cca3be68a2ff0fd5ebb6de25e4eac", // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: [
// "AMap.ControlBar",
// "AMap.ToolBar",
// "AMap.Weather",
// "AMap.CitySearch",
// "AMap.Marker",
// "AMap.MouseTool",
// "AMap.PolyEditor",
// "AMap.Polyline",
// "AMap.Geolocation",
// "AMap.GraspRoad",
// "AMap.Geocoder",
// "AMap.GeometryUtil.ringArea",
// "AMap.DistrictSearch",
// "AMap.MoveAnimation",
"AMap.Driving", // 驾车路线路径规划
], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
})
.then((AMap) => {
this.map = new AMap.Map("containerMap", {
// 设置地图容器id
// rotateEnable: true, // 旋转
// pitchEnable: true, // 倾斜
zoom: 13, // 初始化地图层级
// pitch: 50, // 倾斜角度
// rotation: -15, // 地图旋转角度
// viewMode: "3D", //开启3D视图,默认为关闭
zooms: [2, 20], // 设置地图显示范围
center: [119.419251, 32.400703], // 设置地图中心点
mapStyle: "amap://styles/blue", //设置地图的显示样式
WebGLParams: {
preserveDrawingBuffer: true, // 使用html2canvas截取需要设置该属性,否则截取不到地图
},
});
this.map.on("complete", () => {
console.log("地图加载完成");
this.isSave = true;
this.createFireMarker();
//可以监听到拖动到地图
this.map.on("mouseover", this.onMouseOver);
getPoliceDetailApi(this.policeId).then((res) => {
if (res.data.screenshotParam) {
this.list = JSON.parse(res.data.screenshotParam);
this.showMarker();
}
});
});
this.map.on("click", (e) => {
// e 是事件对象,包含了点击的位置等信息
var lnglat = e.lnglat; // 获取经纬度坐标
console.log("地图被点击,坐标:" + lnglat.lng + ", " + lnglat.lat);
this.showEdit = false;
// 在此处可以进行进一步的操作,如弹出信息窗口、绘制标记等
});
})
.catch((e) => {
console.log(e);
});
},
//----------添加警情中心点标记 -------
createFireMarker() {
var marker = new AMap.Marker({
position: new AMap.LngLat(...this.position),
icon: new AMap.Icon({
image: fireIcon,
imageSize: new AMap.Size(32, 42),
}),
// zIndex: 200,
});
this.map.add(marker);
// 设置地图中心点
this.map.setCenter(new AMap.LngLat(...this.position));
},
onDragStart(event) {
// console.log("Drag start", event, event.target.dataset.index);
//event.dataTransfer.setData(
// "application/index",
// event.target.dataset.index
//);
// 你还可以在这里做其他事情,比如改变元素的样式或状态
this.draggingEnded = false;
this.index = event.target.dataset.index * 1;
},
onDragEnd(event) {
// console.log(
// "Drag end",
// event,
// event.dataTransfer.getData("application/index")
// );
//const data = event.dataTransfer.getData("application/index"); // 获取拖动时设置的数据
// console.log("接收到的数据:", data);
// 拖拽结束时,你可以做一些清理工作,例如重置元素样式或状态
this.draggingEnded = true;
},
onMouseOver(event) {
// console.log("mouseover", event.lnglat);
if (this.draggingEnded) {
// 转换鼠标位置为地理坐标
this.draggingEnded = false;
this.createMarker([event.lnglat.lng, event.lnglat.lat]);
}
},
// 页面一进来拿到上次的list渲染出来
showMarker() {
this.list.forEach((item, index) => {
item.show = true;
item.marker = null;
item.icon = [icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8][
item.id * 1
];
var markerContent =
'<div class="custom-content-marker" >' +
'<img style="transform:rotate(' +
item.rotate +
"deg) scale(" +
item.scale +
');width:60px;height:60px" src=" ' +
item.icon +
'">' +
"</div>";
item.marker = new AMap.Marker({
position: new AMap.LngLat(...item.lnglat),
content: markerContent,
// 以 icon 的 [center bottom] 为原点
offset: new AMap.Pixel(-25, -50),
// zIndex: 200,
cursor: "move",
draggable: true,
});
this.map.add(item.marker);
// 监听点点击事件
this.list[index].marker.on("click", (e) => {
this.item = this.list[index];
this.scale = this.item.scale;
this.rotate = this.item.rotate;
this.showEdit = true;
//拖动坐标获取新坐标
console.log("点击:", this.item.id);
});
// 监听点拖动更新坐标
this.list[index].marker.on("dragend", (e) => {
this.list[index].lnglat = [
this.list[index].marker.getPosition().lng,
this.list[index].marker.getPosition().lat,
];
this.item = this.list[index];
this.scale = this.item.scale;
this.rotate = this.item.rotate;
this.showEdit = true;
//拖动坐标获取新坐标
console.log(
"最新坐标:",
[
this.list[index].marker.getPosition().lng,
this.list[index].marker.getPosition().lat,
],
this.list,
this.item
);
});
});
console.log("createMarker", this.list);
},
// 从左侧拖动过来新建点
createMarker(lnglat) {
let length = this.list.length;
this.list.push({
id: this.index,
lnglat: lnglat,
icon: this.tab[this.index].icon,
marker: null,
scale: 1,
rotate: 0,
show: true,
});
this.item = this.list[length];
console.log("createMarker", this.index);
var markerContent =
'<div class="custom-content-marker" >' +
'<img style="transform:rotate(' +
this.item.rotate +
"deg) scale(" +
this.item.scale +
');width:60px;height:60px" src=" ' +
this.item.icon +
'">' +
"</div>";
this.item.marker = new AMap.Marker({
position: new AMap.LngLat(...this.item.lnglat),
content: markerContent,
// 以 icon 的 [center bottom] 为原点
offset: new AMap.Pixel(-25, -50),
// zIndex: 200,
cursor: "move",
draggable: true,
});
this.map.add(this.item.marker);
this.showEdit = true;
this.scale = this.item.scale;
this.rotate = this.item.rotate;
console.log("createMarker", this.list, this.item);
// 监听点点击事件
this.list[length].marker.on("click", (e) => {
this.item = this.list[length];
this.scale = this.item.scale;
this.rotate = this.item.rotate;
this.showEdit = true;
//拖动坐标获取新坐标
console.log("点击:", this.item.id);
});
// 监听点拖动更新坐标
this.list[length].marker.on("dragend", (e) => {
this.list[length].lnglat = [
this.list[length].marker.getPosition().lng,
this.list[length].marker.getPosition().lat,
];
this.item = this.list[length];
this.scale = this.item.scale;
this.rotate = this.item.rotate;
this.showEdit = true;
//拖动坐标获取新坐标
console.log(
"最新坐标:",
[
this.list[length].marker.getPosition().lng,
this.list[length].marker.getPosition().lat,
],
this.list,
this.item
);
});
},
// 编辑点重新渲染
editMarker() {
var index = this.list.indexOf(this.item);
console.log("编辑", this.rotate, this.scale, this.list[index]);
this.list[index].scale = this.scale;
this.list[index].rotate = this.rotate;
this.map.remove(this.list[index].marker);
this.list[index].marker = null;
var markerContent =
'<div class="custom-content-marker" >' +
'<img style="transform:rotate(' +
this.list[index].rotate +
"deg) scale(" +
this.list[index].scale +
');width:60px;height:60px" src=" ' +
this.list[index].icon +
'">' +
"</div>";
console.log("编辑", markerContent);
this.list[index].marker = new AMap.Marker({
position: new AMap.LngLat(...this.list[index].lnglat),
content: markerContent,
// 以 icon 的 [center bottom] 为原点
offset: new AMap.Pixel(-25, -50),
// zIndex: 200,
cursor: "move",
draggable: true,
});
this.map.add(this.list[index].marker);
// 监听点点击事件
this.list[index].marker.on("click", (e) => {
this.item = this.list[index];
this.scale = this.list[index].scale;
this.rotate = this.list[index].rotate;
this.showEdit = true;
//拖动坐标获取新坐标
console.log("点击11:", this.item.id);
});
// 监听点拖动更新坐标
this.list[index].marker.on("dragend", (e) => {
this.item = this.list[index];
this.item.lnglat = [
this.list[index].marker.getPosition().lng,
this.list[index].marker.getPosition().lat,
];
this.scale = this.list[index].scale;
this.rotate = this.list[index].rotate;
this.showEdit = true;
});
},
// 删除点
removeMarker() {
var index = this.list.indexOf(this.item);
this.list[index].show = false;
this.map.remove(this.list[index].marker);
this.item = {};
this.showEdit = false;
console.log("删除", this.list, this.item, index);
},
/* -----------------------------下发作战--------------------- */
issueImg() {
this.showMenu = false;
let arr = this.list.filter((item) => item.show);
let arr1 = arr.map((item) => {
return {
id: item.id,
lnglat: item.lnglat,
scale: item.scale,
rotate: item.rotate,
};
});
html2canvas(this.$refs.htmlImg, {
useCORS: true, //保证跨域图片的显示,如果为不添加改属性,或者值为false,地图底图不显示
x: window.pageXOffset, //页面在水平方向的滚动距离
y: window.pageYOffset, //页面在垂直方向的滚动距离
}).then((canvas) => {
var img = new Image();
var canvas2 = document.getElementById("myCanvas");
var ctx = canvas2.getContext("2d");
ctx.fillStyle = "#FFFFFF"; //画布填充色
ctx.lineWidth = "1";
ctx.rect(20, 30, canvas2.width - 40, canvas2.height - 60); //矩形距离画布左上角水平和垂直距离,矩形的宽高
ctx.stroke();
img.src = canvas.toDataURL();
var url = canvas.toDataURL("image/png");
const blobImage = this.dataURLtoBlob(url);
let fileName = `htmlImg_${new Date().getTime()}.jpg`;
const fileOfBlob = new File([blobImage], fileName);
let formData = new FormData();
formData.append("file", fileOfBlob, fileName);
this.isSave = false;
uploadHtmlImg(formData).then((res) => {
this.showMenu = true;
this.isSave = true;
// this.$modal.msgSuccess("上传成功");
let saveObj = {
policeId: this.$route.query.id,
// policeId: 196,
fileName: res.fileName,
url: res.url,
screenshotParam: JSON.stringify(arr1),
};
dispatchHtmlImg(saveObj).then((res) => {
this.$modal.msgSuccess("标绘下发成功,可在小程序对应警情中查看");
});
console.log("http://192.168.0.19:12020" + res.url);
// console.log(this.baseUrl + res.url);
});
});
},
// 转成bolb对象
dataURLtoBlob(dataUrl) {
let arr = dataUrl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {
type: mime,
});
},
},
};
</script>
<style scoped lang="scss">
@import "./components/css/rem.scss";
.index5 {
.home {
width: 50px;
position: fixed;
right: 20px;
top: 20px;
z-index: 9999;
}
.left {
width: 280px;
left: 0;
top: 10%;
.img-bg {
width: 50px;
height: 50px;
margin: auto;
}
}
.right {
width: 360px;
// height: 280px;
right: 50px;
bottom: 50px;
.editBox {
background: #0005495d;
background-image: url("./components/img/index5-bg-1.png");
background-repeat: no-repeat; /* 防止重复平铺 */
background-position: center; /* 居中对齐 */
background-size: 100% 100%; /* 根据容器大小等比例缩放至最大尺寸 */
background-attachment: local;
.editContent {
// background-image: url("./components/img/index5-bg-2.png");
// background-repeat: no-repeat; /* 防止重复平铺 */
// background-position: center; /* 居中对齐 */
// background-size: 100% 100%; /* 根据容器大小等比例缩放至最大尺寸 */
// background-attachment: local;
}
}
}
::v-deep .el-slider__runway {
background-color: rgba(0, 255, 255, 0.253);
}
::v-deep .el-slider__bar {
background-color: aqua;
}
::v-deep .el-slider__button {
border: 2px solid aqua;
}
::v-deep .amap-marker-label {
background: rgba(0, 0, 0, 0);
color: aqua;
border: none;
}
::v-deep .amap-icon {
width: 50px !important;
height: 50px !important;
}
.title {
font-size: 0.2rem;
font-weight: 700;
text-shadow: 0px 3px 7px #006cbf;
img {
width: 0.4rem;
height: 0.4rem;
}
}
.carInfo {
position: absolute;
border-radius: 10px;
border: 1px solid cyan;
background: rgba(0, 50, 73, 0.8);
// left: 120px;
// top: 230px;
// background: url("./components/img/car-bg.png") no-repeat center center;
background-size: 100% 100%;
padding: 16px 10px 14px 20px;
::v-deep .dv-water-pond-level text {
font-size: 15px;
font-weight: normal !important;
color: #fff !important;
}
}
}
.main {
height: 1600px;
width: 100%;
background: #d4edff;
}
.svg {
border: 1px solid red;
width: 100px;
height: 100px;
}
</style>