vue手写签名(移动端竖屏),拿来即用,可转为横屏

一、vue手写签名(移动端竖屏)

<template>
  <div class="canvas">
    <div class="canvas_header">手写签名</div>
    <div class="canvas_canvas">
      <canvas id="myCanvas" width="350" height="400"></canvas>
    </div>
    <div class="canvas_info">
      <span @click="showColorDiv()"
        >*请在输入框写入您的姓名</span
      >
    </div>
    <div class="canvas_footer">
      <div @click="clearArea()" class="canvas_footer_re">重写</div>
      <div @click="saveImage()" class="canvas_footer_sa">保存</div>
      <div @click="saveImageInfo()" class="canvas_footer_su">提交</div>
    </div>
    <!-- 颜色选择器 -->
    <div class="canvas_color" v-show="showColor == 2">
      <div>
        <input v-model="strokeStyle" type="color" />
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      touchPressed: false,
      ctx: null,
      strokeStyle: "#000000", //书写颜色
      lineWidth: 4, //线条宽度
      lastX: null,
      lastY: null,
      canvas: null,
      showColor: 1, //显示颜色
      sColor: 0, //显示颜色
    };
  },
  mounted() {
    this.$nextTick(() => {
      let canvas = document.getElementById("myCanvas");
      this.canvas = canvas;
      this.ctx = canvas.getContext("2d");
      //   let winW = window.innerWidth;
      //   let winH = window.innerHeight;
      //   let winW = window.innerWidth;
      //   let winH = window.innerHeight;
      //   canvas.width = winW;
      //   canvas.height = winH;
      this.Init();
    });
  },
  methods: {
    Init() {
      // 移动前
      this.canvas.addEventListener(
        "touchstart",
        (event) => {
          if (event.targetTouches.length == 1) {
            event.preventDefault(); // 阻止浏览器默认事件,重要
            var touch = event.targetTouches[0];
            this.touchPressed = true;
            this.draw(
              touch.pageX - this.canvas.offsetLeft,
              touch.pageY - this.canvas.offsetTop,
              false
            );
          }
        },
        false
      );
      // 移动中
      this.canvas.addEventListener(
        "touchmove",
        (event) => {
          if (event.targetTouches.length == 1) {
            event.preventDefault(); // 阻止浏览器默认事件,重要
            var touch = event.targetTouches[0];
            if (this.touchPressed) {
              this.draw(
                touch.pageX - this.canvas.offsetLeft,
                touch.pageY - this.canvas.offsetTop,
                true
              );
            }
          }
        },
        false
      );
      // 移动结束
      this.canvas.addEventListener(
        "touchend",
        (event) => {
          if (event.targetTouches.length == 1) {
            event.preventDefault(); // 阻止浏览器默认事件,防止手写的时候拖动屏幕,重要
            this.touchPressed = false;
          }
        },
        false
      );
    },
    draw(x, y, isDown) {
      let ctx = this.ctx;
      if (isDown) {
        ctx.beginPath();
        ctx.strokeStyle = this.strokeStyle;
        ctx.lineWidth = this.lineWidth;
        ctx.lineJoin = "round";
        ctx.moveTo(this.lastX, this.lastY);
        ctx.lineTo(x, y);
        ctx.closePath();
        ctx.stroke();
      }
      this.lastX = x;
      this.lastY = y;
    },
    // 重写
    clearArea() {
      this.ctx.setTransform(1, 0, 0, 1, 0, 0);
      this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
    },
    // 保存本地
    saveImage() {
      let a = document.createElement("a");
      a.href = this.canvas.toDataURL();
      a.download = "sign";
      a.click(); //保存
    },
    // 保存服务器
    saveImageInfo() {
      let b = this.canvas.toDataURL();
      console.log(b, "bbb");
    },
    // 弹出颜色
    showColorDiv() {
      return
      this.sColor += 1;
      if (this.sColor == 10) {
        this.showColor = 2;
      }
    },
 	//签完名的图片旋转处理
 	// src为你、base64编码;edg为角度,0-360;callback回调
	rotateBase64Img(src, edg, callback) {
	  var canvas = document.createElement("canvas");
	  var ctx = canvas.getContext("2d");
	  var imgW;//图片宽度
	  var imgH;//图片高度
	  var size;//canvas初始大小
	  if (edg % 90 != 0) {
	      console.error("旋转角度必须是90的倍数!");
	      throw '旋转角度必须是90的倍数!';
	  }
	  (edg < 0) && (edg = (edg % 360) + 360)
	  const quadrant = (edg / 90) % 4; //旋转象限
	  const cutCoor = {sx: 0, sy: 0, ex: 0, ey: 0}; //裁剪坐标
	  var image = new Image();
	  image.crossOrigin = "anonymous"
	  image.src = src;
	  image.onload = function () {
	      imgW = image.width;
	      imgH = image.height;
	      size = imgW > imgH ? imgW : imgH;
	      canvas.width = size * 2;
	      canvas.height = size * 2;
	      switch (quadrant) {
	          case 0:
	              cutCoor.sx = size;
	              cutCoor.sy = size;
	              cutCoor.ex = size + imgW;
	              cutCoor.ey = size + imgH;
	              break;
	          case 1:
	              cutCoor.sx = size - imgH;
	              cutCoor.sy = size;
	              cutCoor.ex = size;
	              cutCoor.ey = size + imgW;
	              break;
	          case 2:
	              cutCoor.sx = size - imgW;
	              cutCoor.sy = size - imgH;
	              cutCoor.ex = size;
	              cutCoor.ey = size;
	              break;
	          case 3:
	              cutCoor.sx = size;
	              cutCoor.sy = size - imgW;
	              cutCoor.ex = size + imgH;
	              cutCoor.ey = size + imgW;
	              break;
	      }
	      ctx.translate(size, size);
	      ctx.rotate(edg * Math.PI / 180);
	      ctx.drawImage(image, 0, 0);
	      var imgData = ctx.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey);
	      if (quadrant % 2 == 0) {
	          canvas.width = imgW;
	          canvas.height = imgH;
	      } else {
	          canvas.width = imgH;
	          canvas.height = imgW;
	      }
	      ctx.putImageData(imgData, 0, 0);
	      callback(canvas.toDataURL())
	  };
	}
    //end
  },
  watch: {
    strokeStyle(newColor,oldColor) {
      console.log(newColor)
    },
  },
};
</script>
<style>
.canvas_header {
  width: 100%;
  text-align: center;
  line-height: 50px;
  font-weight: 800;
  font-size: 20px;
}
.canvas_canvas {
  width: 350px;
  margin: 0 auto;
  border: 1px solid #aaa;
}
.canvas_info {
  margin: 10px 8%;
  font-size: 12px;
}
.canvas_footer {
  width: 80%;
  margin: 10px 10%;
  display: flex;
  justify-content: space-between;
  line-height: 40px;
  text-align: center;
  color: white;
  font-weight: 800;
}
.canvas_footer_re {
  width: 100px;
  background: #f11919;
  border-radius: 10px;
}
.canvas_footer_sa {
  width: 100px;
  background: #1989f1;
  border-radius: 10px;
}
.canvas_footer_su {
  width: 100px;
  background: #2dcb7a;
  border-radius: 10px;
}
</style>
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
要在Vue移动端实现横屏手写签名功能,可以使用HTML5的canvas元素和JavaScript来实现。首先,你需要创建一个canvas元素,并设置其宽高比,以便在横屏模式下正确显示。然后,你需要监听设备方向变化事件,根据设备方向动态调整canvas元素的宽高比,以便在横屏模式下正确显示。最后,你需要监听用户手写事件,并在canvas元素上绘制用户手写签名。 以下是示例代码,可以在移动设备上测试: ```html <template> <div class="canvas-container"> <canvas ref="canvas"></canvas> </div> </template> <script> export default { mounted() { // 监听设备方向变化事件 window.addEventListener("orientationchange", this.onOrientationChange); // 初始化canvas this.initCanvas(); }, methods: { initCanvas() { const canvas = this.$refs.canvas; const ctx = canvas.getContext("2d"); // 设置canvas宽高比为3:2 canvas.width = 300; canvas.height = 200; // 监听用户手写事件 canvas.addEventListener("touchstart", this.onTouchStart); canvas.addEventListener("touchmove", this.onTouchMove); canvas.addEventListener("touchend", this.onTouchEnd); }, onOrientationChange() { const canvas = this.$refs.canvas; const ctx = canvas.getContext("2d"); // 根据设备方向动态调整canvas宽高比 if (window.orientation === 90 || window.orientation === -90) { canvas.width = 200; canvas.height = 300; } else { canvas.width = 300; canvas.height = 200; } // 清空canvas ctx.clearRect(0, 0, canvas.width, canvas.height); }, onTouchStart(event) { const canvas = this.$refs.canvas; const ctx = canvas.getContext("2d"); // 开始绘制路径 ctx.beginPath(); // 获取触点位置 const touch = event.touches[0]; const x = touch.pageX - canvas.offsetLeft; const y = touch.pageY - canvas.offsetTop; // 移动到触点位置 ctx.moveTo(x, y); }, onTouchMove(event) { const canvas = this.$refs.canvas; const ctx = canvas.getContext("2d"); // 获取触点位置 const touch = event.touches[0]; const x = touch.pageX - canvas.offsetLeft; const y = touch.pageY - canvas.offsetTop; // 绘制直线到触点位置 ctx.lineTo(x, y); ctx.stroke(); }, onTouchEnd() { const canvas = this.$refs.canvas; const ctx = canvas.getContext("2d"); // 结束路径绘制 ctx.closePath(); } }, beforeDestroy() { // 移除事件监听 window.removeEventListener("orientationchange", this.onOrientationChange); const canvas = this.$refs.canvas; canvas.removeEventListener("touchstart", this.onTouchStart); canvas.removeEventListener("touchmove", this.onTouchMove); canvas.removeEventListener("touchend", this.onTouchEnd); } }; </script> <style scoped> .canvas-container { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } canvas { border: 1px solid #ccc; } </style> ``` 在上面的示例中,我们创建了一个canvas元素,并设置了其宽高比为3:2,以便在竖屏模式下正确显示。我们还监听了设备方向变化事件,根据设备方向动态调整canvas元素的宽高比。我们还监听了用户手写事件,并在canvas元素上绘制用户手写签名。当用户完成签名后,可以将canvas元素上的图像数据保存到服务器或本地存储中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值