H5学习——canvas与屏幕之间的坐标转换

本文介绍在Canvas绘图中,如何将基于document的鼠标点击坐标转换为基于Canvas原点的坐标,以便于更精确地进行绘图操作。文章提供了具体的代码实现,并建议在实际应用中将坐标转换封装为函数,以提高代码的复用性和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在canvas的使用中,经常会用到鼠标进行交互,但是在交互的过程中难免会遇到一些问题,例如,对于一个居中显示的画布,如图所示
图1
众所周知,canvas的绘制过程中,是以画布的左上顶点为原点进行绘制,假如此时使用鼠标点击事件获取画布左上顶点的坐标,得到的结果为
图2
可见,得到的坐标并非是期望中的(0, 0)或者是和(0, 0)相近的值,这是由于鼠标事件是以document的左上角为原点获取坐标的,因此,为了便于canvas和鼠标的交互,需要对坐标进行转换。

考虑canvas中的一个点基于document的坐标(x, y),由文档结构知,假设canvas距离左边缘和上边缘的距离分别为left, top,此点基于canvas的坐标值应当为(x - left, y - top)

代码的实现过程中,需要使用到canvas.getBoundingclientRect()这个函数

var canvasBound = canvas.getBoundingClientRect()
canvas.onmousedown = function(e){
	console.log((e.clientX-canvasBound.left) + " , " + (e.clientY-canvasBound.top));
}

此时,点击canvas左上角,得到的坐标为
图3
可见,此时的坐标近似为(0, 0)点,至此,坐标转换完成

完整代码

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>坐标转换</title>
    <style>
    	#canvas{
    		border: 1px solid #000000;
    		display:block;
    		margin:0 auto;
    	}
    </style>
</head>
<body>

    <canvas id="canvas">
    </canvas>

    <script>
    	window.onload = function(){
			var canvas = document.getElementById("canvas");
			canvas.width = 400;
			canvas.height = 400;
			var context = canvas.getContext("2d");	
			
			
			var canvasBound = canvas.getBoundingClientRect()
			canvas.onmousedown = function(e){
				console.log((e.clientX-canvasBound.left) + " , " + (e.clientY-canvasBound.top));
			}
			
		}
    </script>
</body>
</html>

如果在工程中使用坐标转换,可以将坐标转换封装在函数中,便于重复使用

function coordinateTrans( x , y ){
   	var canvasBound = canvas.getBoundingClientRect()
   	return {x:(x-canvasBound.left) , y:(y-canvasBound.top)}
}
### 如何在H5网页上对PDF进行手写签名编辑 #### 实现方案概述 要在H5页面中实现对PDF文件的手写签字功能,通常涉及以下几个方面: - **加载PDF文件**:通过JavaScript库(如`pdf.js`)来解析显示PDF文档。 - **创建手写板**:利用HTML5中的Canvas元素作为手写区域,允许用户绘制签名。 - **将签名嵌入到指定位置**:可以采用两种方式处理: - 将签名转换成图像格式,并将其放置于特定坐标处; - 或者直接操作PDF内部结构,在合适的位置插入矢量图形表示的签名。 对于多页PDF的情况,确保每一页都能独立展示并支持单独添加签名是非常重要的。如果遇到分页时内容被不恰当切割的问题,则需调整CSS样式或使用专门针对PDF渲染优化过的框架[^3]。 #### 技术细节说明 ##### 加载PDF文件 借助开源工具[pdf.js](https://mozilla.github.io/pdf.js/)可以在浏览器端轻松完成这项工作。该库提供了丰富的接口用于控制PDF视图的各种属性,比如缩放比例、旋转角度等。 ```javascript // 初始化 PDFJS对象 const loadingTask = pdfjsLib.getDocument('example.pdf'); loadingTask.promise.then(function(pdf){ console.log('Document loaded successfully.'); }, function(error){ console.error('Error while loading document:', error); }); ``` ##### 创建手写板 基于Canvas API构建交互式的绘图界面非常简单直观。下面是一个简单的例子展示了如何捕捉触摸事件并在屏幕上留下痕迹。 ```html <canvas id="signature-pad"></canvas> <script type="text/javascript"> var canvas = document.getElementById("signature-pad"); if (canvas.getContext) { var ctx = canvas.getContext('2d'); let drawing = false; // 开始绘画 canvas.addEventListener('mousedown', () => {drawing=true; }); canvas.addEventListener('touchstart', () => {drawing=true; }); // 移动过程中持续更新路径 canvas.addEventListener('mousemove', draw, false); canvas.addEventListener('touchmove', draw, false); // 结束绘画 canvas.addEventListener('mouseup', stopDrawing, false); canvas.addEventListener('mouseout', stopDrawing, false); canvas.addEventListener('touchend', stopDrawing, false); function draw(e){ if(!drawing){return;} const rect = this.getBoundingClientRect(); const x = e.clientX || e.touches[0].clientX; const y = e.clientY || e.touches[0].clientY; ctx.lineTo(x - rect.left,y - rect.top); ctx.stroke(); } function stopDrawing(){ drawing=false; ctx.beginPath(); } } </script> ``` ##### 嵌入手写签名字样至PDF内 一旦获取到了用户的签名数据,就可以考虑怎样把它应用回原始PDF上了。一种常见的做法就是先转存为PNG/JPEG形式的小图片再粘贴上去;另一种更高级的方式则是尝试修改底层PDF流以容纳新的SVG描述信息。 考虑到兼容性易用性的平衡,推荐前者——即把签名导出为位图资源后再拼接到目标页面里去。具体来说,可以通过调用`toDataURL()`方法获得Base64编码后的字符串表达式,之后交给服务器端脚本进一步加工处理即可[^4]。 ```javascript function saveSignatureAsImage() { const dataURL = canvas.toDataURL('image/png'); fetch('/api/save-signature',{ method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({dataUrl:dataURL}) }) } saveSignatureAsImage(); ``` #### 关键API介绍 在整个流程当中有几个核心组件值得特别关注: - `pdf.js`: 负责读取本地存储或是远程地址上的PDF资料,并提供一系列实用函数帮助开发者自定义呈现逻辑。 - Canvas Element & Context Object: 构建灵活可控的手写输入环境的核心部件之一。 - Fetch API / XMLHttpRequests: 客户端发起HTTP请求的标准手段,可用于上传已生成好的签名素材给后台做后续处置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值