每天bug---用canvas实现手写签名出现轨迹错乱(重要的是苹果手机和安卓手机错乱不一致!)
用canvas实现手写签名出现轨迹错乱(重要的是苹果手机和安卓手机错乱不一致!)
·
Canvas可以用来实现手写签名的功能,但在苹果手机上,可能会因为触摸屏幕采样率的问题导致轨迹不一致。下面是一些可能有用的解决方法:
使用更高的Canvas分辨率。增加Canvas的分辨率可以提高触摸屏幕的采样率,从而使得轨迹更加精细。可以通过修改Canvas的大小和像素密度来实现。
减少Canvas绘制的速度。在绘制签名时,可以设置较慢的绘制速度,这样可以让Canvas在绘制线条时更加平滑,从而减少轨迹不一致的问题。
使用插值算法。插值算法可以将离散的点插值为连续的曲线,从而使得绘制的轨迹更加平滑。常见的插值算法包括Bezier曲线和样条曲线。
增加触摸屏幕的采样率。在某些情况下,轨迹不一致的问题可能是由于触摸屏幕的采样率太低导致的。可以通过调整手机的设置来增加触摸屏幕的采样率。
希望这些方法可以帮助你解决苹果手机上Canvas绘制手写签名时轨迹不一致的问题。
一、首先来实现下这个签字的功能
原理呢就是使用canvas标签进行绘制路线的。
<body> 及样式
<style>
.canvasBox {
height: 300px;
width: 300px;
box-shadow: 5px 5px 5px 5px;
margin-top: 200px;
/* position: fixed;
top: 200px; */
}
</style>
<body>
<button class="cleanContent" onclick="cleanContent()">
重写
</button>
<button class="cleanContent" onclick="returnContent()">
撤销
</button>
<div class="canvasBox">
<canvas id="canvasF" onmouseup="mouseup(event)" onmousemove="mousemove(event)" onmousedown="mousedown(event)"
height="300px" width="300px"></canvas>
</div>
</body>
2.准备变量和方法
const canvas = document.getElementById('canvasF');
const ctx = canvas.getContext('2d');
var isDrawing = false;
var lastX = 0; //开始滑动x
var lastY = 0; //开始滑动y
var afterX = 0; //结束滑动的x
var afterY = 0; //结束滑动时y
var storageSteps = []; //每结束滑动后存一次 ,为了撤销做准备
// 开始移动
function mousedown(e) {
console.log('mousedown',);
isDrawing = true;
lastX = e.clientX || e.touches[0].clientX;
lastY = e.clientY || e.touches[0].clientY;
}
// 正在移动
function mousemove(e) {
if (!isDrawing) return;
console.log('mousemove');
const currentX = e.clientX || e.touches[0].clientX;
const currentY = e.clientY || e.touches[0].clientY;
ctx.beginPath();
// moveTo(x,y)方法理解, 里面的参数:指的是距离 “canves画布” 左上方 的距离;所以不能用原来的lastX和lastY。lineTo()方法同理
// getBoundingClientRect() 方法用来获取元素的width、height、及距页面可视区域的横纵距离(x,y)还有元素本身距离可是页面的top、left、bottom、right
// console.log('canvas.canvasRect',canvas.getBoundingClientRect());
// 获取canvas标签元素距离页面可视区域的距离。
let h = canvas.getBoundingClientRect().top;
let w = canvas.getBoundingClientRect().left;
// 注意这里如果不减,直接用的的话,会出现鼠标与描点对不上的情况。
ctx.moveTo(lastX - w, lastY - h);
ctx.lineTo(currentX - w, currentY - h);
ctx.stroke();
lastX = currentX;
lastY = currentY;
}
// 结束移动
function mouseup(e) {
console.log('mouseup');
isDrawing = false;
//结束一笔时,将该记录存进数组storageSteps中
afterX = e.clientX;
afterY = e.clientY;
// console.log('ctx--------------',ctx);
let imgData = ctx.getImageData(0, 0, 300, 300) // 绘制结束记录当前画布信息(这里参数代表要获取具体标量的画布内容)
console.log('imgData---------', imgData)
storageSteps.push(imgData); //存储到数组中
console.log('storageSteps---------', storageSteps)
}
// 清空
function cleanContent() {
// 清空画布
// 清空方式有很多。重置画布大小时和给画布新背景时,可以清空内容
// clearRect() 函数可以指定起始点的x, y 位置以及宽度和高度来清除画布
ctx.clearRect(0, 0, canvas.width, canvas.height)
}
// 撤销
function returnContent() {
// 核心是putImageData() 函数,重新绘制storageSteps[len - 1]的内容
storageSteps.pop()
const len = storageSteps.length;
if (len) {
ctx.putImageData(storageSteps[len - 1], 0, 0);
} else {
cleanContent()
}
console.log('storageSteps---------', storageSteps)
}
二、问题
三、解决
这里不能自己写死!
但是在苹果上面还是出现这种问题!
所以我根据在模拟机上根据显示屏的大小重新算了一遍!然后得到比例。注意!这个公式并不适合所有的苹果错乱问题,因为和签字框的显示位置有关。
等我理清楚了再来完善
更多推荐
已为社区贡献2条内容
所有评论(0)