canvas画板绘制踩坑,移动pc双端

133 阅读1分钟

最近写了一个需求,需要在浏览器绘制,就去百度[canvas手写绘制](canvas手写绘制_百度搜索 (baidu.com)) 挑了一个自认为清晰的学习(复制)了

<canvas
    id="canvas"
    width="600"
    height="600"
    @mousedown="canvasDown($event)"
    @mousemove="canvasMove($event)"
    @mouseup="canvasUp()"
    @mouseleave="canvasLeave()"
    ref="canvas"
  >
canvasDown(e) {
        this.canvasMoveUse = true;
        const canvasX = e.clientX - e.target.offsetLeft + document.documentElement.scrollLeft;
        const canvasY = e.clientY - e.target.offsetTop + document.documentElement.scrollTop;
        this.ctx.beginPath(); // 移动的起点
        this.ctx.moveTo(canvasX, canvasY);
    },
    canvasMove(e) {
      // 只在移动是进行绘制图线
      if (this.canvasMoveUse) {
        const t = e.target;
        let canvasX = e.clientX - t.offsetLeft + document.documentElement.scrollLeft;
        let canvasY = e.clientY - t.offsetTop + document.documentElement.scrollTop;
        this.ctx.lineTo(canvasX, canvasY);
        this.ctx.stroke();
      }
    },
    canvasUp() {
      this.canvasMoveUse = false;
    },
    canvasLeave() {
      this.canvasMoveUse = false;
    },

代码如图所示,在浏览器本地运行也ok,当我把代码上传到服务器,并觉得这次太简单的时候,问题就来了,代码在手机端完全没办法运行,没有绘制痕迹,经过一番查找,发现问题出在了cavans的设备兼容上,上述代码在pc可以正常运行,但不适配移动端,那要怎么同时适配pc和移动端呢?

这里需要用到一个浏览器方法navigator.userAgent,这个方法可以返回打开的浏览器环境,判断设备是移动还是pc,navigator.userAgent.match(/Mobile/),稍微加个检索方法,加可以简单区分设备,pc返回null,这样就可以区分设备分开操作,先把代码放上

EquipmentJudgment(){
      const isMobile = navigator.userAgent.match(/Mobile/)
      console.log(isMobile);
      if (isMobile) {
        this.isPc = false
      } else {
        this.isPc = true
      }
    },

光是这样还不行,因为canvas的方法还是不同步,为了不出问题,我还加了if判断渲染

<canvas
        id="canvas"
        width="600"
        height="600"
        @mousedown="canvasDown($event)"
        @mousemove="canvasMove($event)"
        @mouseup="canvasUp()"
        @mouseleave="canvasLeave()"
        ref="canvas"
        v-if="isPc"
      >
        抱歉,您的浏览器暂不支持canvas元素
      </canvas>
      <canvas
        id="canvas"
        width="600"
        height="600"
        @touchstart="canvasDown($event)"
        @touchmove="canvasMove($event)"
        @touchend="canvasUp()"
        @mouseleave="canvasLeave()"
        ref="canvas"
        v-if="!isPc"
      >
        抱歉,您的浏览器暂不支持canvas元素
      </canvas>

并且在vue的mounted生命周期监视设备变换,随时切换

mounted() {
    this.EquipmentJudgment()
    this.$nextTick(() => {
      this.show();
    })
    window.onresize = () => {
      this.EquipmentJudgment()
      this.$nextTick(() => {
        this.show();
      })
    }
  },

最后,这是修改过的绘制代码

canvasDown(e) {
        this.canvasMoveUse = true;
        const canvasX = this.isPc ? 
          e.clientX - e.target.offsetLeft + document.documentElement.scrollLeft : 
          e.touches[0].clientX - e.target.offsetLeft;
        const canvasY = this.isPc ? 
          e.clientY - e.target.offsetTop + document.documentElement.scrollTop : 
          e.touches[0].clientY - e.target.offsetTop;
        this.ctx.beginPath(); // 移动的起点
        this.ctx.moveTo(canvasX, canvasY);
    },
    canvasMove(e) {
      // 只在移动是进行绘制图线
      if (this.canvasMoveUse) {
        const t = e.target;
        let canvasX = this.isPc ?
          e.clientX - t.offsetLeft + document.documentElement.scrollLeft :
          e.touches[0].clientX - e.target.offsetLeft;
        let canvasY = this.isPc ?
          e.clientY - t.offsetTop + document.documentElement.scrollTop : 
          e.touches[0].clientY - e.target.offsetTop;
        this.ctx.lineTo(canvasX, canvasY);
        this.ctx.stroke();
      }
    },