一、在pc端使用
1.html
注意点:canvas跟其他标签一样,也可以通过css来定义样式。但这里需要注意的是:canvas的默认宽高为300px * 150px,在css中为canvas定义宽高,实际上把宽高为300px * 150px的画布进行了拉伸,如果在这样的情况下进行canvas绘图,你得到的图形可能就是变形的效果。所以,在canvas绘图时,应该在canvas标签里直接定义宽高。
<canvas id="Canvas" width="880" height="400"></canvas>
<canvas id="nullCanvas" width="880" height="400" style="display: none;"></canvas> //用于判断画布内容是否为空时做对比
<img [src]="option.signatureImg">//展示签字内容
2.js
let canvas = <HTMLCanvasElement>document.getElementById('Canvas'); //获取画布ID
let nullCanvas = <HTMLCanvasElement>document.getElementById('nullCanvas');//获取一个空画布用于下方保存画布内容时判断画布是否为空
let saveEl = document.getElementById('saveCanvas');//获取保存按钮
let clearEl = document.getElementById('clearCanvas');//获取清空按钮
let context = canvas.getContext('2d');//获取画笔
var ISmousedown = false; // 定义鼠标按下前为false
// 监听鼠标按下
canvas.onmousedown = (e) => {
// 获取在canvas上的x,y轴坐标
let x = e['layerX'];
let y = e['layerY'];
context.beginPath(); // 开始一条路径
context.moveTo(x, y); // 把路径移动到画布中的指定点
ISmousedown = true;
};
// 监听鼠标移动
canvas.onmousemove = (e) => {
// 在鼠标按下时有效
if (ISmousedown) {
// 获取在canvas上的x,y轴坐标
let x = e['layerX'];
let y = e['layerY'];
context.strokeStyle = "#000000"; // 设置线条的颜色
context.lineWidth = 2;//设置线条的粗细
context.lineCap = 'round'; // 线条末端添加圆形线帽,减少线条的生硬感
context.lineJoin = 'round'; // 线条交汇时为原型边角
// 利用阴影,消除锯齿
context.shadowBlur = 1;
context.shadowColor = '#000000';
context.lineTo(x, y); // 添加一个新点,然后在画布中创建从该点到最后指定点的线条
context.stroke(); // 在画布上绘制确切的路径
}
};
// 监听鼠标抬起
canvas.onmouseup = () => {
context.closePath(); //结束本次绘画
ISmousedown = false;
};
//监听清除按钮
clearEl.onclick = () => {
context.clearRect(0, 0, canvas.width, canvas.height);//清楚画布内容
};
//监听保存按钮
saveEl.onclick = () => {
let imgBase64 = canvas.toDataURL();//将画布内容转换为base64
//判断画布内容是否为空
if (imgBase64 == nullCanvas.toDataURL()) {
toastr.error('请签名后再保存!');
return;
}
this.option.signatureImg = imgBase64;//将转换得到的base64赋值到相应的地方用<img>标签展示
};
二、在移动端使用
1.html
<canvas id="Canvas" width="550" height="400"></canvas>
<canvas id="nullCanvas" width="550" height="400" style="display: none;"></canvas> //用于判断画布内容是否为空时做对比
<img [src]="option.signatureImg">//展示签字内容
2.js
let canvas = <HTMLCanvasElement>document.getElementById('Canvas'); //获取画布ID
let nullCanvas = <HTMLCanvasElement>document.getElementById('nullCanvas'); //获取一个空画布用于下方保存画布内容时判断画布是否为空
let saveEl = document.getElementById('saveCanvas');//获取保存按钮
let clearEl = document.getElementById('clearCanvas');//获取清空按钮
let context = canvas.getContext('2d');//获取画笔
let rect = canvas.getBoundingClientRect();//查询画布在页面中的坐标
//按下
canvas.ontouchstart = (e) => {
e.preventDefault();//页面有滚动条时限制页面在签字过程中滚动
let start_x = e.touches[0].clientX - rect.left;//用鼠标x轴的位置减去画布左边距得到鼠标在画布中x轴的开始位置
let start_y = e.touches[0].clientY - rect.top;//用鼠标y轴的位置减去画布上边距得到鼠标在画布中y轴的开始位置
//开始本次绘画
context.beginPath();
//画笔起始点
context.moveTo(start_x, start_y);
};
//移动
canvas.ontouchmove = (e) => {
let move_x = e.touches[0].clientX - rect.left;
let move_y = e.touches[0].clientY - rect.top;
context.strokeStyle = "#000000";//画线颜色
context.lineWidth = 2;//画线粗细
context.lineCap = 'round'; // 线条末端添加圆形线帽,减少线条的生硬感
context.lineJoin = 'round'; // 线条交汇时为原型边角
// 利用阴影,消除锯齿
context.shadowBlur = 1;
context.shadowColor = '#000000';
//根据鼠标路径绘画
context.lineTo(move_x, move_y);
//立即渲染
context.stroke();
};
//松开
canvas.ontouchend = (e) => {
//结束本次绘画
context.closePath();
};
//清空画布内容
clearEl.onclick = () => {
context.clearRect(0, 0, canvas.width, canvas.height);
};
//保存画布内容
saveEl.onclick = () => {
let imgBase64 = canvas.toDataURL();
//判断画布内容是否为空
if (imgBase64 == nullCanvas.toDataURL()) {
toastr.error('请签名后再保存!');
return;
}
this.option.signatureImg = imgBase64;//将转换得到的base64赋值到相应的地方用<img>标签展示
};
三、注意点
1.pc端的监听事件与移动端不同
2.移动端页面如果出现滚动条,需要让页面每次刷新都回到顶部,不然画出的线的位置会出现偏移