微日志_免费提供日志记录|作品展示|学习教程|免费日记

PointerEvent的使用以及注意事项

pointerevent 压感 阅读:42

体验地址:暂无地址

在早期的浏览器,输入的事件其实相对单纯,只有考虑到鼠标和键盘两种;而当时的鼠标事件,其实就是 click、mousedown、mouseup 等等的事件。但是当手机、平板开始流行时候,再移动装置上的主要操作界面,已经从鼠标变成是触控了~

由于触控和鼠标的操作逻辑,算是有根本上的差异的,再加上大部分的装置又支持多点触控,所以虽然浏览器大多会把触控的事件对应回传统的鼠标事件,但是如果希望能有更细致的操作,传统的鼠标事件是不够用的。

而目前 W3C 针对触控操作的部分,则有两种事件模型可以使用,其中一个是专门为了触控设计的 Touch Event,这应该算是目前大部分移动浏览器所支持的事件架构;而另一种,则是由微软所提出的、试图统一所有指针装置的事件架构、Pointer Event。

相较于目前主流的 Touch Event (W3C)只有去处理触控的事件,微软提出的 Pointer Event 则是希望能把所有的指针事件都统一来做管理、让程序开发时能更简单地使用。以目前定义的标准来说,Pointer Event (W3C)能支持的指针装置包括了鼠标、触控(手指)、以及笔型装置;而除了能整合不同类型的指针装置外,Pointer Event 针对能支持的硬件,也多了相当多额外的参数,像是压力、宽度、高度,甚至比型装置的倾斜程度等等。

这些更详细的资讯,基本上都是可以让开发者根据各种指针装置的输入,来做更细致的处理的~再加上透过 Pointer Event 的架构,可以一次性地处理掉鼠标和触控等装置的事件,所以在 Heresy 来看,应该算是一种相对好的架构。

最近开发一个系统,需要使用到压感,进行手写内容,根据压力程度不同,线条的粗细不一样,为了实现这个功能,查询了一系列api,最终确定使用pointer event来实现。

在实现过程中,均没有什么问题,就是一样的绑定事件,然后进行绘制就可以了,代码如下:

let canvas = document.querySelector('#canvas')
canvas.addEventListener('pointerdown',canvasMouseDown);
canvas.addEventListener('pointermove',canvasMouseMove);
canvas.addEventListener('pointerup',canvasMouseUp);

在对应的方法里面进行编写对应的逻辑即可,编写完成后,鼠标模式下没有任何问题,部分逻辑代码:

function canvasMouseDown(e) {
if (app.toolsSelectIndex == -1 || app.toolsSelectIndex == 5) return;
if (!drawingIsConnected()) return;
if (!app.isDrawingStart && app.currentPageId != -1) getRequestDrawing(getIndexForPage(app.pageIndex));
if (e.buttons) {
app.lastX = e.offsetX / app.scaleRate;
app.lastY = e.offsetY / app.scaleRate;
    } else {
var p = $('#whiteboard').position();
var offsetTop = p.top;
var offsetLeft = p.left;

if (e.target != null) {
offsetTop += e.target.offsetTop;
offsetLeft += e.target.offsetLeft;
        }
app.lastX = (e.targetTouches[0].pageX - offsetLeft) / app.scaleRate;
app.lastY = (e.targetTouches[0].pageY - offsetTop) / app.scaleRate;
    }
var pressure = e.pressure || 0.5;
drawLineInPage(-1, pressure, app.lastX, app.lastY, app.lastX, app.lastY);
startDrawing(app.lastX, app.lastY,Math.floor(pressure * 256));
}
function canvasMouseUp(e) {
if (!drawingIsConnected()) return;
finishDrawing();
}

function canvasMouseMove(e) {
if (!drawingIsConnected()) return;
var x = e.offsetX / app.scaleRate;
var y = e.offsetY / app.scaleRate;
if (app.drawingStartedFlag && e.buttons == 1) {
var pressure = e.pressure || 0.5;
if (Math.abs(x - app.lastX) <= DRAWING_RESOLUTION && Math.abs(y - app.lastY) <= DRAWING_RESOLUTION) return;
if (Math.abs(x - app.lastX) <= 127 && Math.abs(y - app.lastY) <= 127) {
var ox = x - app.lastX;
var oy = y - app.lastY;
if (ox != 0 || oy != 0) {
updateDrawing(ox, oy,Math.floor(pressure * 255));
drawLineInPage(-1, pressure, app.lastX, app.lastY, x, y);
app.lastX += ox;
app.lastY += oy;
            }
        } else {
restartDrawing(app.lastX, app.lastY,Math.floor(pressure * 255));
drawLineInPage(-1, pressure, app.lastX, app.lastY, x, y);
app.lastX = x;
app.lastY = y;
        }
    }
if (e.buttons == 0)finishDrawing();
app.hostX = x;
app.hostY = y;
updateHostPointer(app.hostX, app.hostY);
}

但是使用手绘板的时候,发现画笔永远只是在对应画笔圈内生效,否则就会调用pointercancel事件,这个事件有点类似touchcancel,解决这个问题的方法如下:

解决这个问题,就需要把所有的对应监听对象的手势操作禁用掉,否则手绘板的就会一直出现这个问题,只需要简单的给对应的dom对象加上,touch-action:none;即可解决。

canvas{
touch-action: none;
}

如果觉得帮助到您的话,支持一下呗!