Canvas可以用来实现手写签名的功能,但在苹果手机上,可能会因为触摸屏幕采样率的问题导致轨迹不一致。下面是一些可能有用的解决方法:

使用更高的Canvas分辨率。增加Canvas的分辨率可以提高触摸屏幕的采样率,从而使得轨迹更加精细。可以通过修改Canvas的大小和像素密度来实现。

减少Canvas绘制的速度。在绘制签名时,可以设置较慢的绘制速度,这样可以让Canvas在绘制线条时更加平滑,从而减少轨迹不一致的问题。

使用插值算法。插值算法可以将离散的点插值为连续的曲线,从而使得绘制的轨迹更加平滑。常见的插值算法包括Bezier曲线和样条曲线。

增加触摸屏幕的采样率。在某些情况下,轨迹不一致的问题可能是由于触摸屏幕的采样率太低导致的。可以通过调整手机的设置来增加触摸屏幕的采样率。

希望这些方法可以帮助你解决苹果手机上Canvas绘制手写签名时轨迹不一致的问题。

一、首先来实现下这个签字的功能

原理呢就是使用canvas标签进行绘制路线的。

  1. <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)
    }
二、问题
三、解决

这里不能自己写死!

但是在苹果上面还是出现这种问题!

所以我根据在模拟机上根据显示屏的大小重新算了一遍!然后得到比例。注意!这个公式并不适合所有的苹果错乱问题,因为和签字框的显示位置有关。

等我理清楚了再来完善

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐