- 定义数据与类型
/* 画布数据 */ 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;
- 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); });
- 初始化位置数据,定义画布信息,确定起始点,添加移动监听
/* 初始化数据 */ 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); };
- 定义绘制方法
/* 开始绘制 */ const draw = (event: any) => { // 获取当前坐标点位 const { offsetX, offsetY } = mobileStatus ? event.changedTouches[0] : event; // 修改最后一次绘制的坐标点 client.endX = offsetX; client.endY = offsetY; // 根据坐标点位移动添加线条 ctx.lineTo(offsetX, offsetY); // 绘制 ctx.stroke(); };
- 定义结束方法,移除滑动监听事件
/* 结束绘制 */ const cloaseDraw = () => { // 结束绘制 ctx.closePath(); // 移除鼠标移动或手势移动监听器 window.removeEventListener("mousemove", draw); };
- 定义取消事件,清楚绘制内容
/* 取消保存 */ const closeCan = () => { // 清空当前画布上的所有绘制内容 ctx.clearRect(0, 0, config.width, config.height); };
- 定义保存事件,生成图片
/* 保存画布 */ 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(); }); };
- 最终展示