1.引用插件element-ui 使用自动化布局以及日期,时间选择器

<template>
  <div class="personnel-management all detail" id="personnelManagements">
    <el-row :gutter="20" class="el-row-index" style="margin: 0">
      <div style="height: 100%">
        <el-col
          class="el-col-index"
          :xs="24"
          :sm="24"
          :md="24"
          :lg="24"
          :xl="24"
        >
          <div class="number-rosters gm-item">
            <p class="gm-title">canvas图片绘制</p>
            <div class="gm-info" style="display: flex">
              <img class="gm-img" src="../../static/img/line.png" alt="" />

              <div style="width: 100%; height: 100%; position: relative">
                <div
                  id="bottom"
                  style="
                    width: 50%;
                    height: 100%;
                    border: 1px solid #2999ff;
                    position: absolute;
                    left: 25%;
                    right: 25%;
                  "
                >
                  <div class="area" style="height: 100%">
                    <ul style="width: 100%; display: flex" id="bottomul">
                      <li>
                        <el-date-picker
                          v-model="form2.date"
                          value-format="yyyy-MM-dd"
                          @blur="verifyDate"
                          type="date"
                          placeholder="选择日期"
                        ></el-date-picker>
                      </li>
                      <li>
                        <el-time-picker
                          id="date"
                          placeholder="起始时间"
                          @blur="getScope"
                          v-model="form2.startTime"
                        >
                        </el-time-picker>
                      </li>
                      <li>
                        <el-time-picker
                          id="date2"
                          placeholder="结束时间"
                          v-model="form2.endTime"
                          @change="verify"
                          :picker-options="{ selectableRange: endValue }"
                        >
                        </el-time-picker>
                      </li>
                      <li>
                        <el-button
                          size="small"
                          @click="submit"
                          style="border-radius: 0%"
                          >查询</el-button
                        >
                      </li>
                    </ul>
                    <div
                      class="bg"
                      style="overflow: hidden; width: 100%; position: relative"
                    >
                      <img
                        src="背景图片路径"
                        :style="{
                          width: imgwidth + 'px',
                          height: imghight + 'px',
                        }"
                      />
                      <canvas
                        id="canvas"
                        style="position: absolute; left: 0; top: 0"
                        :style="{
                          width: imgwidth + 'px',
                          height: imghight + 'px',
                        }"
                      ></canvas>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </el-col>
      </div>
    </el-row>
  </div>
</template>

2.其中canvas的宽高是根据整个div父级宽度的大小自定义,img只是作为背景图片贴到上面,而canvas更是贴到最上层来绘制路径

<script>
//引入图片路径防止图片不显示
import actionup from "../../static/img/actionup.png";
import actionover from "../../static/img/actionover.png";

export default {
  name: "",
  data() {
    return {
      //返回时间参数用于传入后端数据记录时间段的定位信息
      form2: {
        date:
          new Date().getFullYear() +
          "-" +
          (new Date().getMonth() + 1) +
          "-" +
          new Date().getDate(),
        startTime: new Date(new Date().setHours(0, 0, 0, 0)),
        endTime: new Date(new Date().getTime()),
      },
      //实际宽高所占用的布局
      imghight: 0,
      imgwidth: 0,
      baiimghight: 0,
      baiimgwidth: 0,
      //接口调用传递的参数
      deviceNo: "",
    };
  },
  computed: {
    projectId() {
      return localStorage.getItem("projectId")
        ? localStorage.getItem("projectId")
        : "aaaaaaaaaaaaaaaaaaaaaaa";
    },
  },
  async mounted() {
    //接口调用传递的参数
    this.deviceNo = this.$route.query.deviceNo;
    
    //用于拿到每一块区域的实际宽高
    const el = document.getElementById("bottom");
    const els = document.getElementById("bottomul");
    this.imghight = el.offsetHeight - els.offsetHeight;
    this.imgwidth = el.offsetWidth;

    //每百分之一距离y轴
    this.baiimghight = this.imghight / 100;
    //每百分之一距离x轴
    this.baiimgwidth = this.imgwidth / 100;

    this.getToken(() => {
      const startDate =
        this.p(this.form2.startTime.getHours()) +
        ":" +
        this.p(this.form2.startTime.getMinutes()) +
        ":" +
        this.p(this.form2.startTime.getSeconds());
      const endTimeDate =
        this.p(this.form2.endTime.getHours()) +
        ":" +
        this.p(this.form2.endTime.getMinutes()) +
        ":" +
        this.p(this.form2.endTime.getSeconds());
      var startTime = this.form2.date + " " + startDate;
      var endTime = this.form2.date + " " + endTimeDate;
      console.log(startTime);
      console.log(endTime);
      this.gmHttp.get(
        this.gmApi.getHelmetListByDeviceNoV1,
        { startTime, endTime, deviceNo: this.deviceNo },
        this.$store.state.token,
        (res) => {
          if (res.code == "200") {
            this.locationList = res.data || [];
            this.addOverlay();
          } else this.$message.error(this.gmLang.NETWORK_ERROR);
        }
      );
    });
  },
  methods: {
    p(m) {
      return m < 9 ? "0" + m : m;
    },

    // 获取token
    async getToken(callback) {
      if (this.$store.state.token) return callback();
      const res = await this.gmHttp.get(
        this.gmApi.avoidLanding,
        { id: this.projectId },
        "",
        () => {}
      );
      if (res.code == "200") {
        this.$store.commit("setToken", res.data.token);
        callback();
      } else this.$message.error(this.gmLang.NETWORK_ERROR);
    },

    submit() {
      //点击确定的时候清空画布
      var c = document.getElementById("canvas");
      c.height = c.height;
      this.getHelmetListByDeviceNo();
    },

    getHelmetListByDeviceNo() {
      if (!this.form2.date) {
        return this.$message.warning("请选择日期");
      }
      if (!this.form2.startTime) {
        return this.$message.warning("请选择起始时间");
      }
      if (!this.form2.endTime) {
        return this.$message.warning("请选择结束时间");
      }

      //调用时间转换获取开始时间和结束时间
      const startDate =
        this.p(this.form2.startTime.getHours()) +
        ":" +
        this.p(this.form2.startTime.getMinutes()) +
        ":" +
        this.p(this.form2.startTime.getSeconds());
      const endTimeDate =
        this.p(this.form2.endTime.getHours()) +
        ":" +
        this.p(this.form2.endTime.getMinutes()) +
        ":" +
        this.p(this.form2.endTime.getSeconds());

      var startTime = this.form2.date + " " + startDate;
      var endTime = this.form2.date + " " + endTimeDate;

      this.gmHttp.get(
        this.gmApi.getHelmetListByDeviceNoV1,
        { startTime, endTime, deviceNo: this.deviceNo },
        this.$store.state.token,
        (res) => {
          if (res.code == "200") {
            this.locationList = res.data || [];
            this.addOverlay();
          } else this.$message.error(this.gmLang.NETWORK_ERROR);
        }
      );
    },

    addOverlay() {
      //获得画板
      var c = document.getElementById("canvas");
      //获得绘画环境
      var cv = c.getContext("2d");
      //定义canvas所属宽高
      c.width = c.clientWidth * window.devicePixelRatio;
      c.height = c.clientHeight * window.devicePixelRatio;
      //定义线条宽度
      cv.lineWidth = 1;
      //电源线条颜色
      cv.strokeStyle = "green";
      //边角类型lineJoin='边叫类型'  边角类型:bevel:斜角,round:圆角,miter:尖角
      cv.lineJoin = "round";
      //根据屏幕大小自适应放大和缩小线条,大屏可视化必备
      cv.scale(window.devicePixelRatio, window.devicePixelRatio);
      //开启绘画路径(声明开始划线)
      cv.beginPath();
      //获取起点位置,主要是在起点图片
      var xx = 0;
      var yy = 0;
      for (var i = 0; i < this.locationList.length; i++) {
        xx = this.locationList[0].relativeX;
        yy = this.locationList[0].relativeY;
      }

      var xj = this.baiimgwidth;

      var yj = this.baiimghight;

      cv.moveTo(xj * xx, yj * yy);
      //获取终点位置,在终点绘制终点图片
      var xt = "";
      var yt = "";
      for (var i = 0; i < this.locationList.length; i++) {
        cv.lineTo(
          xj * Math.floor(this.locationList[i].relativeX),
          yj * Math.floor(this.locationList[i].relativeY)
        );
        cv.stroke();
        xt = xj * Math.floor(this.locationList[i].relativeX);
        yt = yj * Math.floor(this.locationList[i].relativeY);
      }

      this.huihua(xj * xx, yj * yy);
      this.huihuatwo(xt, yt);
    },

    //在起点绘制图片
    huihua(x, y) {
      var ctx = document.getElementById("canvas").getContext("2d");
      var img = new Image();
      img.src = actionup;
      img.onload = function () {
        ctx.drawImage(img, x - 14, y - 30, 30, 30);
      };
    },
    //在终点绘制图片
    huihuatwo(xt, yt) {
      var ctx = document.getElementById("canvas").getContext("2d");
      var imgtext = new Image();
      imgtext.src = actionover;
      imgtext.onload = function () {
        ctx.drawImage(imgtext, xt - 14, yt - 30, 30, 30);
      };
    },
  },
};
</script>

效果

 

 

Logo

前往低代码交流专区

更多推荐