ctx.lineWidth = 3; // 设置线宽
ctx.strokeStyle = ‘red’; // 设置路径颜色
ctx.moveTo(beginX, beginY); // 从(beginX, beginY)这个坐标点开始画图
ctx.lineTo(stopX, stopY); // 定义从(beginX, beginY)到(stopX, stopY)的线条(该方法不会创建线条)
ctx.closePath(); // 创建该条路径
ctx.stroke(); // 实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径。默认颜色是黑色。
};
3. 注册监听事件
let beginX: number, beginY: number;
const canvas: HTMLCanvasElement = canvasDom.current;
const ctx = canvas.getContext(‘2d’);
ctx.fillStyle = ‘#fff’;
ctx.fillRect(0, 0, canvas.width, canvas.height);
canvas.addEventListener(‘touchstart’, function(event: any) {
event.preventDefault(); // 阻止在canvas画布上签名的时候页面跟着滚动
beginX = event.touches[0].clientX - this.offsetLeft;
beginY = event.touches[0].pageY - this.offsetTop;
});
canvas.addEventListener(‘touchmove’, (event: any) => {
event.preventDefault(); // 阻止在canvas画布上签名的时候页面跟着滚动
event = event.touches[0];
let stopX = event.clientX - canvas.offsetLeft;
let stopY = event.pageY - canvas.offsetTop;
writing(beginX, beginY, stopX, stopY, ctx);
beginX = stopX; // 这一步很关键,需要不断更新起点,否则画出来的是射线簇
beginY = stopY;
});
注意
:
-
在注册“touchstart”和“touchmove”事件时,需要阻止默认事件,否则页面会跟着手势上下滑动。
-
移动端的每个触摸事件对象中都包括了touches这个属性,它用于描述位于屏幕上的所有手指的一个列表,获取当前事件对象我们习惯性的使用event = event.touches[0],而在PC端则不需要这么操作。
-
offsetLeft值跟offsetTop值跟父级元素没关系,而是跟其上一级的定位元素(除position:static外的所有定位如fixed,relative,absolute元素)有关系。若上一级定位元素都没有除position:staice外的定位,则这个偏移量是相对于body而言的。
-
需要理清移动端事件对象的几个属性,⏬
clientX/clientY: 触摸位置距离当前body可视区域的x,y坐标;
pageX/pageY: 对于整个页面来说,触摸位置距离body左上角的x,y坐标,包括被scrollTop和scrollLeft的值;
screenX/screenY: 触摸位置距离显示器左边和顶部的x,y距离。
所以,在获取结束点坐标的时候,如果当前页面没有出现滚动条,使用clientY和pageY计算差别不大,如果页面比较长,出现了滚动条,那么就必须要使用pageY来计算。clientX同理,但是移动端通常横向滚动的场景不多,所以用clientX来计算即可。
- 在签名(touchmove)这个动作过程中,我们需要不断的更新起点位置,否则画出来是这样???
其实这个原理和微积分很相似,线段本质上就是由无穷多个小线段组成,宏观一点来看可以把线段当成一个个长度很小的小线段首尾相连构成。所以我一直觉得编程编到最后就是考验一个人的数学能力,交并集、逻辑思维、算法等都能看到数学的身影。最后生成签名如下:
生成PDF文档
=======
html2canvas是一款将HTML代码转换成Canvas的插件,因此需要用一个div包裹住需要打印的内容区域,获得这个dom节点。
html2Canvas(dom, {
allowTaint: true,
width: dom.offsetWidth, //设置获取到的canvas宽度
height: dom.offsetHeight, //设置获取到的canvas高度
x: 0, //页面在水平方向滚动的距离
y: 0, //页面在垂直方向滚动的距离
})
注意
:此处需要设置width和height及x,y,否则当页面内容只有一页的时候没有问题,但是若页面内容有很多页的时候,就会出现生成的图片只有一小部分有内容的现象。问题就出现在这个配置参数上,若没有设置宽高,则默认只取当前视口的内容,丢弃掉其他超出当前视口的内容。
设置打印参数:
const print = () => {
let dom: HTMLElement = pdfDom.current;
html2Canvas(dom, {
allowTaint: true,
width: dom.offsetWidth, //设置获取到的canvas宽度
height: dom.offsetHeight, //设置获取到的canvas高度
x: 0, //页面在水平方向滚动的距离
y: 0, //页面在垂直方向滚动的距离
}).then((canvas: HTMLCanvasElement) => {
let canvasWidth = canvas.width;
let canvasHeight = canvas.height;
let pageHeight = (canvasWidth / 592.28) * 841.89; // 一页A4 pdf能显示的canvas高度
let imgWidth = 595.28; // 设置图片宽度和A4纸宽度相等
let imgHeight = (592.28 / canvasWidth) * canvasHeight;//等比例换算成A4纸的高度
let totalHeight = imgHeight; // 需要打印的图片总高度,初始状态和图片高度相等
let pageData = canvas.toDataURL(‘image/png’, 1.0);
let PDF = new JsPDF(‘p’, ‘pt’, ‘a4’, true);
if (totalHeight < pageHeight) { //
PDF.addImage(pageData, ‘JPEG’, 0, 0, imgWidth, imgHeight); // 从顶部开始打印
} else {
let top = 0; // 打印初始区域
while (totalHeight > 0) {
PDF.addImage(pageData, ‘JPEG’, 0, top, imgWidth, imgHeight); // 从图片顶部往下top位置开始打印
totalHeight -= pageHeight;
top -= 841.89;
if (totalHeight > 0) {
PDF.addPage();
}
}
}
PDF.save(‘test.pdf’);
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数同学面临毕业设计项目选题时,很多人都会感到无从下手,尤其是对于计算机专业的学生来说,选择一个合适的题目尤为重要。因为毕业设计不仅是我们在大学四年学习的一个总结,更是展示自己能力的重要机会。
因此收集整理了一份《2024年计算机毕业设计项目大全》,初衷也很简单,就是希望能够帮助提高效率,同时减轻大家的负担。
既有Java、Web、PHP、也有C、小程序、Python等项目供你选择,真正体系化!
由于项目比较多,这里只是将部分目录截图出来,每个节点里面都包含素材文档、项目源码、讲解视频
如果你觉得这些内容对你有帮助,可以添加VX:vip1024c (备注项目大全获取)
(img-q9ftwCnZ-1712518802734)]
既有Java、Web、PHP、也有C、小程序、Python等项目供你选择,真正体系化!
由于项目比较多,这里只是将部分目录截图出来,每个节点里面都包含素材文档、项目源码、讲解视频
如果你觉得这些内容对你有帮助,可以添加VX:vip1024c (备注项目大全获取)
[外链图片转存中…(img-EwGOmUfI-1712518802735)]