|
@@ -0,0 +1,469 @@
|
|
|
+<template>
|
|
|
+ <canvas id="myCanvas" class="canvas-dom" style="boder: 1px solid red">
|
|
|
+ </canvas>
|
|
|
+</template>
|
|
|
+
|
|
|
+ <script lang="ts">
|
|
|
+import { Search } from "vant";
|
|
|
+import { number } from "echarts";
|
|
|
+import { getMapInfo } from "@/apis/envmonitor";
|
|
|
+import { defineComponent, nextTick, onMounted, reactive, toRefs } from "vue";
|
|
|
+import { parseImgUrl } from "@/utils";
|
|
|
+import { swiper } from "@/utils/swiper";
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ components: {
|
|
|
+ VanSearch: Search,
|
|
|
+ },
|
|
|
+ setup() {
|
|
|
+ let spaceList: any = [];
|
|
|
+ let ctx: any = {};
|
|
|
+ let centerObj: any = {};
|
|
|
+ const proxyData = reactive({
|
|
|
+ spaceList: spaceList,
|
|
|
+ copySpaceArr: spaceList,
|
|
|
+ parseImgUrl: parseImgUrl,
|
|
|
+ spaceName: "",
|
|
|
+ width: 3361.136,
|
|
|
+ height: 2729.25,
|
|
|
+ scale: 1,
|
|
|
+ ctx: ctx,
|
|
|
+ centerObj: centerObj,
|
|
|
+ // 搜索某个空间
|
|
|
+ searchSpace() {
|
|
|
+ proxyData.spaceList.map((item: any) => {
|
|
|
+ // debugger
|
|
|
+ console.log(item.localName == proxyData.spaceName);
|
|
|
+ console.log("搜索====");
|
|
|
+ console.log(item.localName);
|
|
|
+ console.log(proxyData.spaceName);
|
|
|
+ if (item.localName == proxyData.spaceName) {
|
|
|
+ console.log("搜索到某个空间");
|
|
|
+ item.fillColor = "red";
|
|
|
+ item.shadow = true;
|
|
|
+ proxyData.initCanvas();
|
|
|
+ } else {
|
|
|
+ // item.shadow = false;
|
|
|
+ // item.fillColor = "#ececec";
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 放大
|
|
|
+ zommAdd() {
|
|
|
+ console.log("被点击了");
|
|
|
+ if (proxyData.scale > 3) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ proxyData.scale = proxyData.scale + 0.1;
|
|
|
+ // debugger;
|
|
|
+ proxyData.formSpaceData();
|
|
|
+ proxyData.initCanvas();
|
|
|
+ },
|
|
|
+ // 缩小
|
|
|
+ zommDel() {
|
|
|
+ if (proxyData.scale < 0.3) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ proxyData.scale = proxyData.scale - 0.1;
|
|
|
+ proxyData.formSpaceData();
|
|
|
+ proxyData.initCanvas();
|
|
|
+ },
|
|
|
+ sliderSwiper() {
|
|
|
+ // 获取当前时间的下标
|
|
|
+ let sliderList: any = document.querySelector("#sliderListId");
|
|
|
+ sliderList.addEventListener("touchstart", function (e: any) {});
|
|
|
+ swiper(sliderList, {
|
|
|
+ swipeLeft: function (e: any) {},
|
|
|
+ swipeRight: function (e: any) {},
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // canvas画图
|
|
|
+ initCanvas() {
|
|
|
+ let canvasDom: any = document.querySelector("#myCanvas");
|
|
|
+ let ctx: any = canvasDom.getContext("2d");
|
|
|
+ proxyData.drawDpiBegin(
|
|
|
+ canvasDom,
|
|
|
+ ctx,
|
|
|
+ proxyData.width,
|
|
|
+ proxyData.height
|
|
|
+ );
|
|
|
+ proxyData.ctx = ctx;
|
|
|
+ ctx.clearRect(0, 0, proxyData.width, proxyData.height);
|
|
|
+ ctx.scale(
|
|
|
+ proxyData.scale,
|
|
|
+ proxyData.scale,
|
|
|
+ centerObj.left,
|
|
|
+ centerObj.top
|
|
|
+ );
|
|
|
+
|
|
|
+ proxyData.spaceList.map((item: any) => {
|
|
|
+ // debugger
|
|
|
+ if (item.canClick) {
|
|
|
+ let circleArr: any = item.circlePoint;
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.fillStyle = item.fillColor;
|
|
|
+ let pointLeftArr: any = [];
|
|
|
+ let pointTopArr: any = [];
|
|
|
+
|
|
|
+ item.pointArr.map((childItem: any, index: any) => {
|
|
|
+ // debugger
|
|
|
+ childItem.left = childItem.left;
|
|
|
+ childItem.top = childItem.top;
|
|
|
+ if (index == 0) {
|
|
|
+ ctx.moveTo(childItem.left, childItem.top);
|
|
|
+ } else {
|
|
|
+ ctx.lineTo(childItem.left, childItem.top);
|
|
|
+ }
|
|
|
+ pointLeftArr.push(childItem.left);
|
|
|
+ pointTopArr.push(childItem.top);
|
|
|
+ });
|
|
|
+ // debugger;
|
|
|
+ console.log(item.devicePoint);
|
|
|
+ proxyData.drawIcon(ctx, "coffee.svg", item.devicePoint[0]);
|
|
|
+ // proxyData.drawIcon(ctx, "dev.svg", item.devicePoint[1]);
|
|
|
+ // proxyData.drawIcon(ctx, "deviceroom.svg", item.devicePoint[2]);
|
|
|
+ ctx.closePath();
|
|
|
+ ctx.fill();
|
|
|
+ ctx.lineWidth = 1;
|
|
|
+ ctx.strokeStyle = "rgba(15, 206, 233, 1)";
|
|
|
+ ctx.stroke();
|
|
|
+ ctx.beginPath();
|
|
|
+ if (circleArr && circleArr.length) {
|
|
|
+ console.log(circleArr);
|
|
|
+ ctx.lineTo(circleArr[3].left, circleArr[3].top);
|
|
|
+ ctx.bezierCurveTo(
|
|
|
+ circleArr[2].left,
|
|
|
+ circleArr[2].top,
|
|
|
+ circleArr[1].left,
|
|
|
+ circleArr[1].top,
|
|
|
+ circleArr[0].left,
|
|
|
+ circleArr[0].top
|
|
|
+ );
|
|
|
+ }
|
|
|
+ ctx.closePath();
|
|
|
+ ctx.fill();
|
|
|
+ ctx.lineWidth = 1;
|
|
|
+ ctx.strokeStyle = "rgba(15, 206, 233, 1)";
|
|
|
+ ctx.stroke();
|
|
|
+
|
|
|
+ let min1: any =
|
|
|
+ proxyData.MaxAndMin(pointLeftArr)[1] -
|
|
|
+ proxyData.MaxAndMin(pointLeftArr)[0];
|
|
|
+ let min2: any =
|
|
|
+ proxyData.MaxAndMin(pointTopArr)[1] -
|
|
|
+ proxyData.MaxAndMin(pointTopArr)[0];
|
|
|
+ let min: any = min1 < min2 ? min1 : min2;
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.font = "13px serif";
|
|
|
+ ctx.textAlign = "center";
|
|
|
+ ctx.fillStyle = item.fillColor !== "#ececec" ? "#ffffff" : "red";
|
|
|
+ console.log("min===" + min);
|
|
|
+ if (item.localName && min > 100) {
|
|
|
+ ctx.fillText(
|
|
|
+ item.localName,
|
|
|
+ item.logPointArr[0].left,
|
|
|
+ item.logPointArr[0].top,
|
|
|
+ item.width
|
|
|
+ );
|
|
|
+ }
|
|
|
+ ctx.closePath();
|
|
|
+ if (item.shadow) {
|
|
|
+ item.shadowColor = "#000000";
|
|
|
+ ctx.shadowOffsetX = -50; //阴影x轴位移。正值向右,负值向左。
|
|
|
+ ctx.shadowOffsetY = -50; //阴影y轴位移。正值向下,负值向上。
|
|
|
+ ctx.shadowBlur = 10; //阴影模糊滤镜。数据越大,扩散程度越大。
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ let img: any = new Image();
|
|
|
+ img.src = require("@/assets/svg/bg_disable.png");
|
|
|
+ img.onload = function () {
|
|
|
+ ctx.beginPath();
|
|
|
+ item.pointArr.map((item: any, index: any) => {
|
|
|
+ if (index === 0) {
|
|
|
+ ctx.moveTo(item.left, item.top);
|
|
|
+ } else {
|
|
|
+ ctx.lineTo(item.left, item.top);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // ctx.fillStyle = "#cfefef";
|
|
|
+ // ctx.fill();
|
|
|
+ let pat: any = ctx.createPattern(img, "repeat");
|
|
|
+ ctx.fillStyle = pat;
|
|
|
+ ctx.fill();
|
|
|
+ ctx.closePath();
|
|
|
+ ctx.strokeStyle = "rgba(15, 206, 233, 1)";
|
|
|
+ ctx.stroke();
|
|
|
+ };
|
|
|
+ }
|
|
|
+ });
|
|
|
+ proxyData.drawDpiEnd(canvasDom, ctx);
|
|
|
+ },
|
|
|
+ MaxAndMin(arr: any) {
|
|
|
+ return [Math.min.apply(null, arr), Math.max.apply(null, arr)];
|
|
|
+ },
|
|
|
+ // 绑定事件
|
|
|
+ bindEvent() {
|
|
|
+ let canvasDom: any = document.querySelector("#myCanvas");
|
|
|
+ // 点击事件
|
|
|
+ canvasDom.addEventListener("click", proxyData.detect);
|
|
|
+ },
|
|
|
+ // 解决canvas画图模糊的问题
|
|
|
+ // 开始画
|
|
|
+ drawDpiBegin(dom: any, context: any, width: any, height: any) {
|
|
|
+ context.save();
|
|
|
+ let scaleValue = window.devicePixelRatio;
|
|
|
+ dom.setAttribute("width", width * scaleValue);
|
|
|
+ dom.setAttribute("height", height * scaleValue);
|
|
|
+
|
|
|
+ dom.style.width = width + "px";
|
|
|
+ dom.style.height = height + "px";
|
|
|
+ context.scale(scaleValue, scaleValue);
|
|
|
+ },
|
|
|
+ // 画图介绍
|
|
|
+ drawDpiEnd(dom: any, context: any) {
|
|
|
+ context.restore();
|
|
|
+ },
|
|
|
+ // 地图点击事件
|
|
|
+ detect(event: any) {
|
|
|
+ let canvasDom: any = document.querySelector("#myCanvas");
|
|
|
+ let x: any = event.clientX - canvasDom.getBoundingClientRect().left;
|
|
|
+ let y: any = event.clientY - canvasDom.getBoundingClientRect().top;
|
|
|
+ // let ctx: any = canvasDom.getContext("2d");
|
|
|
+ // proxyData.initCanvas();
|
|
|
+ console.log(event);
|
|
|
+ // alert("点击了!");
|
|
|
+ for (let i = 0; i < proxyData.spaceList.length; i++) {
|
|
|
+ let item: any = proxyData.spaceList[i];
|
|
|
+ let devicePoint: any = item.devicePoint;
|
|
|
+ let pointArr: any = item.pointArr;
|
|
|
+ let iconFlag: any = false;
|
|
|
+ devicePoint.map((dev: any, index: any) => {
|
|
|
+ if (
|
|
|
+ x >= dev.left &&
|
|
|
+ x <= dev.left + 20 &&
|
|
|
+ y >= dev.top &&
|
|
|
+ y < dev.top + 20
|
|
|
+ ) {
|
|
|
+ // alert("我被点了!");
|
|
|
+ // console.log("我被点了!")
|
|
|
+ iconFlag = true;
|
|
|
+ console.log(`我被点了设备图标!${index}`);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (iconFlag) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ let dot: any = {
|
|
|
+ x: x,
|
|
|
+ y: y,
|
|
|
+ };
|
|
|
+ let coordinates: any = pointArr;
|
|
|
+ coordinates.map((item: any) => {
|
|
|
+ item.x = item.left;
|
|
|
+ item.y = item.top;
|
|
|
+ });
|
|
|
+ let flag = proxyData.queryPtInPolygon(dot, coordinates);
|
|
|
+ // console.log(flag);
|
|
|
+ if (flag) {
|
|
|
+ console.log("点击了区域" + item.localName);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ queryPtInPolygon(point: any, polygon: any) {
|
|
|
+ let p1: any = "";
|
|
|
+ let p2: any = "";
|
|
|
+ let p3: any = "";
|
|
|
+ let p4: any = "";
|
|
|
+
|
|
|
+ p1 = point;
|
|
|
+ p2 = { x: 1000000000000, y: point.y };
|
|
|
+
|
|
|
+ let count: any = 0;
|
|
|
+ //对每条边都和射线作对比
|
|
|
+ for (let i = 0; i < polygon.length - 1; i++) {
|
|
|
+ p3 = polygon[i];
|
|
|
+ p4 = polygon[i + 1];
|
|
|
+ if (checkCross(p1, p2, p3, p4) == true) {
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ p3 = polygon[polygon.length - 1];
|
|
|
+
|
|
|
+ p4 = polygon[0];
|
|
|
+ if (checkCross(p1, p2, p3, p4) == true) {
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return count % 2 == 0 ? false : true;
|
|
|
+
|
|
|
+ //判断两条线段是否相交
|
|
|
+ function checkCross(p1: any, p2: any, p3: any, p4: any) {
|
|
|
+ let v1: any = { x: p1.x - p3.x, y: p1.y - p3.y };
|
|
|
+ let v2: any = { x: p2.x - p3.x, y: p2.y - p3.y };
|
|
|
+
|
|
|
+ let v3: any = { x: p4.x - p3.x, y: p4.y - p3.y };
|
|
|
+ let v: any = crossMul(v1, v3) * crossMul(v2, v3);
|
|
|
+
|
|
|
+ v1 = { x: p3.x - p1.x, y: p3.y - p1.y };
|
|
|
+ v2 = { x: p4.x - p1.x, y: p4.y - p1.y };
|
|
|
+
|
|
|
+ v3 = { x: p2.x - p1.x, y: p2.y - p1.y };
|
|
|
+ return v <= 0 && crossMul(v1, v3) * crossMul(v2, v3) <= 0
|
|
|
+ ? true
|
|
|
+ : false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //计算向量叉乘
|
|
|
+ function crossMul(v1: any, v2: any) {
|
|
|
+ return v1.x * v2.y - v1.y * v2.x;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 画图标
|
|
|
+ drawIcon(ctx: any, url: any, iconPerstion: any) {
|
|
|
+ if (iconPerstion) {
|
|
|
+ let img: any = new Image();
|
|
|
+ img.src = require(`@/assets/svg/${url}`);
|
|
|
+ img.onload = function () {
|
|
|
+ ctx.drawImage(img, iconPerstion.left, iconPerstion.top, 25, 15);
|
|
|
+ iconPerstion.width = 30;
|
|
|
+ iconPerstion.height = 30;
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 设置区域颜色
|
|
|
+ setSpaceColor() {
|
|
|
+ proxyData.spaceList.map((item: any, index: any) => {
|
|
|
+ if (index % 2 == 0) {
|
|
|
+ item.fillColor = "#ffcc33";
|
|
|
+ } else if (index % 3 == 0) {
|
|
|
+ item.fillColor = "#ccff99";
|
|
|
+ } else {
|
|
|
+ item.fillColor = "#ececec";
|
|
|
+ }
|
|
|
+ });
|
|
|
+ console.log(proxyData.spaceList);
|
|
|
+ },
|
|
|
+ // 数据格式化
|
|
|
+ formSpaceData() {
|
|
|
+ proxyData.spaceList = JSON.parse(proxyData.copySpaceArr);
|
|
|
+
|
|
|
+ proxyData.spaceList.map((item: any) => {
|
|
|
+ item.fillColor = "#ececec";
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 格式化地图数据
|
|
|
+ formatePage() {
|
|
|
+ let spaceList: any = [
|
|
|
+ {
|
|
|
+ spaceId: "1",
|
|
|
+ localName: "H301",
|
|
|
+ canClick: true,
|
|
|
+ pointArr: [
|
|
|
+ {
|
|
|
+ left: 577.1346,
|
|
|
+ top: 1944.0056,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ left: 577.1346,
|
|
|
+ top: 2160.6334,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ left: 398.5199,
|
|
|
+ top: 2339.25,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ left: 295.3858,
|
|
|
+ top: 2339.25,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ left: 295.3858,
|
|
|
+ top: 1764.7014,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ left: 397.8632,
|
|
|
+ top: 1764.7014,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ devicePoint: [
|
|
|
+ {
|
|
|
+ left: 537.493,
|
|
|
+ top: 2151.2646,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ circlePoint: [],
|
|
|
+ detailPoint: [
|
|
|
+ {
|
|
|
+ left: 317.5158,
|
|
|
+ top: 1797.2386999999999,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ logoPointArr: [
|
|
|
+ {
|
|
|
+ left: 436.2602,
|
|
|
+ top: 2052.1476000000002,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ proxyData.copySpaceArr = JSON.stringify(spaceList);
|
|
|
+ proxyData.formSpaceData();
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取地图信息
|
|
|
+ */
|
|
|
+ getMapInfo() {
|
|
|
+ let params: any = {
|
|
|
+ projectId: "Pj1101080259",
|
|
|
+ floorId: "Fl11010802593241ec348ecb4148806b9034c8957454",
|
|
|
+ };
|
|
|
+ getMapInfo(params)
|
|
|
+ .then((res) => {
|
|
|
+ // debugger
|
|
|
+ let resData: any = res;
|
|
|
+ let data: any = resData?.data ?? null;
|
|
|
+ proxyData.width = data.width;
|
|
|
+ proxyData.height = data.height;
|
|
|
+ proxyData.spaceList = data.spaceList;
|
|
|
+ proxyData.setSpaceColor();
|
|
|
+ proxyData.initCanvas();
|
|
|
+ })
|
|
|
+ .catch(() => {});
|
|
|
+ },
|
|
|
+ });
|
|
|
+ nextTick(() => {
|
|
|
+ proxyData.bindEvent();
|
|
|
+ });
|
|
|
+ onMounted(() => {
|
|
|
+ // proxyData.getMapInfo();
|
|
|
+ proxyData.formatePage();
|
|
|
+ proxyData.initCanvas();
|
|
|
+ });
|
|
|
+ return {
|
|
|
+ ...toRefs(proxyData),
|
|
|
+ };
|
|
|
+ },
|
|
|
+});
|
|
|
+</script>
|
|
|
+ <style lang="scss" scoped>
|
|
|
+.canvas-box {
|
|
|
+ width: 100%;
|
|
|
+ height: calc(100% - 80px);
|
|
|
+ // overflow-x: hidden;
|
|
|
+ // overflow-y: hidden;
|
|
|
+}
|
|
|
+.com-upload {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ // overflow: hidden;
|
|
|
+}
|
|
|
+.space-search {
|
|
|
+ position: fixed;
|
|
|
+ width: 350px;
|
|
|
+ left: 10px;
|
|
|
+ top: 50px;
|
|
|
+ z-index: 333;
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|