Canvas+TS绘制签名

  1. 定义数据与类型
        /* 画布数据 */
        let config: {
          width: number /* 宽 */;
          height: number /* 高 */;
          lineWidth: number /* 线宽 */;
          strokeStyle: string /* 颜色 */;
          lineCap: string /* 线头两端圆角 */;
          lineJoin: string /* 线条交汇圆角 */;
        };
        /* 位置数据 */
        let client : {
          offsetX: number,/* x轴偏移位置 */
          offsetY: number,/* y轴偏移位置 */
          endX: number,/* 页面x轴位置 */
          endY: number,/* 页面y轴位置 */
        };
        /* 设备区分 */
        const mobileStatus = /Mobile|Android|iPhone/i.test(navigator.userAgent);
        /* 画布  */
        let ctx: any, canvas: any;

  2. vue生命周期内定义画布数据,添加监听事件
        onMounted(() => {
          config = {
            width: 400 ,
            height: 200 ,
            lineWidth: 5 ,
            strokeStyle: "red",
            lineCap: "round",
            lineJoin: "round",
          };
          client = {
            offsetX: 0,
            offsetY: 0,
            endX: 0,
            endY: 0,
          }
          /* 定义画布信息 */
          canvas = document.querySelector("canvas");
          canvas.width = config.width;
          canvas.height = config.height;
          canvas.style.border = "1px solid #000";
          ctx = canvas.getContext("2d");
          ctx.fillStyle = "transparent";
          /* 绘制矩形 */
          ctx.fillRect(0, 0, config.width, config.height);
          /* 监听鼠标或者手指滑动开始 */
          window.addEventListener(mobileStatus ? "touchstart" : "mousedown", init);
          /* 监听鼠标或者手指滑动结束 */
          window.addEventListener(mobileStatus ? "touchend" : "mouseup",cloaseDraw);
        });

  3. 初始化位置数据,定义画布信息,确定起始点,添加移动监听
        /* 初始化数据 */
        const init = (even: any) => {
          const { offsetX, offsetY, pageX, pageY } = mobileStatus ? even.changedTouches[0] : even;
          client.offsetX = offsetX;
          client.offsetY = offsetY;
          client.endX = pageX;
          client.endY = pageY;
          ctx.beginPath();
          ctx.lineWidth = config.lineWidth;
          ctx.strokeStyle = config.strokeStyle;
          ctx.lineCap = config.lineCap;
          ctx.lineJoin = config.lineJoin;
          ctx.moveTo(client.offsetX, client.offsetY);
          window.addEventListener(mobileStatus ? "touchmove" : "mousemove", draw);
        };

  4. 定义绘制方法
        /* 开始绘制 */
        const draw = (event: any) => {
          // 获取当前坐标点位
          const { offsetX, offsetY } = mobileStatus ? event.changedTouches[0] : event;
          // 修改最后一次绘制的坐标点
          client.endX = offsetX;
          client.endY = offsetY;
          // 根据坐标点位移动添加线条
          ctx.lineTo(offsetX, offsetY);
          // 绘制
          ctx.stroke();
        };

  5. 定义结束方法,移除滑动监听事件
        /* 结束绘制 */
        const cloaseDraw = () => {
          // 结束绘制
          ctx.closePath();
          // 移除鼠标移动或手势移动监听器
          window.removeEventListener("mousemove", draw);
        };

  6. 定义取消事件,清楚绘制内容
        /* 取消保存 */
        const closeCan = () => {
          // 清空当前画布上的所有绘制内容
          ctx.clearRect(0, 0, config.width, config.height);
        };

  7. 定义保存事件,生成图片
        /* 保存画布 */
        const saveCan = () => {
          // 将canvas上的内容转成blob流
          canvas.toBlob((blob: any) => {
            // 获取当前时间并转成字符串,用来当做文件名
            const date = Date.now().toString();
            // 创建一个 a 标签
            const a = document.createElement("a");
            // 设置 a 标签的下载文件名
            a.download = `${date}.png`;
            // 设置 a 标签的跳转路径为 文件流地址
            a.href = URL.createObjectURL(blob);
            // 手动触发 a 标签的点击事件
            a.click();
            // 移除 a 标签
            a.remove();
          });
        };

  8. 最终展示

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值