即时生成一个需要设置简单快速签名的功能。我正在画布领域写签名。我使用jQuery,但mousemove坐标的刷新率不够快。会发生的是,如果你快速写下你的签名,你会看到一些像素之间的空格。
如何更快地设置mousemove的刷新速度?
$("#xx").mousemove(function(e){
ctx.fillRect(e.pageX - size, e.pageY - size, size, size);
$("#pagex").html(e.pageX - size);
$("#pagey").html(e.pageY - size);
}
答案 0 :(得分:14)
你做不到。 mousemove事件由浏览器生成,因此您可以像浏览器生成它们一样快地接收它们。
浏览器没有义务以任何给定的速率生成事件(通过移动的像素或经过的时间):如果快速移动鼠标,您将看到坐标中的“跳跃”报告,如浏览器正在报告“鼠标移动了,它现在在这里”,而不是“......并经历了这些像素”。实际上,慢速计算机上的浏览器可能会生成较少的mousemove事件,以免页面速度变慢。
你可以做的是用一条直线连接mousemove事件的连续位置 - 这显然不会让你更精确,但它可以减轻影响。
答案 1 :(得分:7)
你需要让你的处理程序更快。
如果该事件的处理程序仍在运行,浏览器可以删除事件,因此您需要尽快退出mousemove处理程序。你可以尝试在那里优化代码或推迟工作直到鼠标移动完成。绘图可能是您正在做的最慢的事情,因此您可以将鼠标移动存储在内存中并稍后绘制。在绘图完成之前,这不会更新显示,但否则会更好。
答案 2 :(得分:2)
你可以根据计时器发射你自己的事件,这可能是一个坏主意,但如果真的需要,那就更好了。
答案 3 :(得分:1)
我建议(增强@river答案):
答案 4 :(得分:0)
其他一些答案表明这是由于处理程序功能缓慢所致。在我的测试中,无论我是在处理程序中使用count++
还是进行更昂贵的画布绘制调用都没有任何区别-两种情况下,在10秒内生成的事件数约为500。但是,这可能在速度较慢的计算机上有所作为。
Apparently大多数鼠标/指针每秒仅向操作系统报告其位置少于100次,因此,这甚至可能不在浏览器的控制范围之内。
您可能需要研究新的PointerEvent.getCoalescedEvents()
方法。来自MDN文档:
getCoalescedEvents()
接口的PointerEvent
方法返回已合并到调度的PointerEvent
事件中的所有pointermove
实例的序列。
这是一个例子:
window.addEventListener("pointermove", function(event) {
let events = event.getCoalescedEvents();
for(let e of events) {
draw(e.pageX, e.pageY);
}
});
但是,在对此进行测试之后,似乎很少能够合并我计算机上的事件。同样,它在速度较慢的计算机上可能更有用。因此,目前最好的方法可能是使用ctx.lineTo
或类似的方法(也许是arcTo
)。这是一个结合getCoalescedEvents
和lineTo
的简单的工作画布演示程序:
<canvas id="canvas" style="touch-action:none; width:100vw; height:100vh; position:fixed; top:0; left:0; right:0; bottom:0;"></canvas>
<script>
let mouseIsDown = false;
let ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
window.addEventListener("pointerdown", function(e) {
ctx.beginPath();
ctx.moveTo(e.pageX, e.pageY);
mouseIsDown = true;
});
window.addEventListener("pointerup", function(e) {
mouseIsDown = false;
});
window.addEventListener("pointermove", function(event) {
if(mouseIsDown) {
let events = event.getCoalescedEvents();
for(let e of events) {
ctx.lineTo(e.pageX, e.pageY);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(e.pageX, e.pageY);
}
}
});
</script>
答案 5 :(得分:0)
您是否尝试过使用 passive: true
和 capture: true
侦听器?通常浏览器会等待 50-200 毫秒来等待 preventDefault()
调用,但使用 passive: true
选项将摆脱这种行为,代价是失去 preventDefault()
。这种滞后就是为什么@vageko4924 在 10 秒内总共看到大约 500 个事件,尽管处理程序效率很高。 capture: true
选项只是确保您的回调在所有其他人之前触发 - 这可以保护您免受缓慢回调的间歇性延迟。
我不确定这在 jQuery 中会是什么样子,但在 vanilla JS 中是这样的:
let x = document.querySelector('#xx'); // which would be faster if it were using getElementById()
x.addEventListener('mousemove', e => {
// Your logic here
}, {passive: true, capture: true});
来源:https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener