HTML5/Js画布在快速移动时捕获鼠标坐标 [英] Html5/Js canvas capturing mouse coords when it moves fast
问题描述
我在画布上画曲线.将基于该曲线绘制onmouseup线,并为其连接特定的x点.
I have a canvas where I draw a curve. onmouseup lines are drawn based on that curve and connecting specific x-points for it.
问题在于,如果鼠标快速快速 移动,它的所有点都不会被捕获.
var canvas;
var ctx;
function drawCanvas(popup) {
var flag = false;
canvas = document.querySelector(popup + " #canvasG");
ctx = canvas.getContext('2d');
var sketch = document.querySelector(popup + " #canvasD");
var sketch_style = getComputedStyle(sketch);
canvas.width = parseInt(sketch_style.getPropertyValue('width'));
canvas.height = parseInt(sketch_style.getPropertyValue('height'));
// Creating a tmp canvas
var tmp_canvas = document.createElement('canvas');
var tmp_ctx = tmp_canvas.getContext('2d');
tmp_canvas.id = 'tmp_canvas';
tmp_canvas.width = canvas.width;
tmp_canvas.height = canvas.height;
sketch.appendChild(tmp_canvas);
var mouse = {x: 0, y: 0};
// Pencil Points
var ppts = [];
var mousXprev = 0;
/* Mouse capturing work -- here is the problem!!! */
tmp_canvas.addEventListener('mousemove', function(e) {
if (!flag) { drawScales(ctx, canvas); flag = true; }
if (mousXprev <= e.offsetX // only allow to draw inside the allowed area
&& e.offsetX > 12 && mouse.x > 12 && e.offsetX <= 12*24+12 && mouse.x < 12*24+12
&& e.offsetY < tmp_canvas.height-28 && mouse.y < tmp_canvas.height-28 && e.offsetY > tmp_canvas.height-224 && mouse.y > tmp_canvas.height-224) {
mouse.x = typeof e.offsetX !== 'undefined' ? e.offsetX : e.layerX;
mousXprev = mouse.x;
mouse.y = typeof e.offsetY !== 'undefined' ? e.offsetY : e.layerY;
} else {
drawLines(tmp_ctx, canvas, ppts);
ppts = []; // clear points
}
}, false);
tmp_ctx.lineWidth = 2;
tmp_ctx.lineJoin = 'round';
tmp_ctx.lineCap = 'round';
tmp_ctx.strokeStyle = 'blue';
tmp_ctx.fillStyle = 'blue';
tmp_canvas.addEventListener('mousedown', function(e) {
tmp_canvas.addEventListener('mousemove', onPaint, false);
mousXprev = 0;
ppts = []; // clear points
ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height); // clear path
drawScales(ctx, canvas);
if (e.offsetX > 12 && e.offsetX <= 12*24+12 && e.offsetY < tmp_canvas.height-28 && e.offsetY > tmp_canvas.height-224) {
mouse.x = typeof e.offsetX !== 'undefined' ? e.offsetX : e.layerX;
mouse.y = typeof e.offsetY !== 'undefined' ? e.offsetY : e.layerY;
ppts.push({x: mouse.x, y: mouse.y});
onPaint();
}
}, false);
tmp_canvas.addEventListener('mouseup', function() {
tmp_canvas.removeEventListener('mousemove', onPaint, false);
if (ppts.length > 1) {
ctx.drawImage(tmp_canvas, 0, 0);
tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
// draw lines...
ppts = [];
}
}, false);
var onPaint = function() {
ppts.push({x: mouse.x, y: mouse.y});
if (ppts.length < 3) {
var b = ppts[0];
tmp_ctx.beginPath();
tmp_ctx.arc(b.x, b.y, tmp_ctx.lineWidth / 2, 0, Math.PI * 2, !0);
tmp_ctx.fill();
tmp_ctx.closePath();
return;
}
tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
tmp_ctx.beginPath();
tmp_ctx.moveTo(ppts[0].x, ppts[0].y);
for (var i = 1; i < ppts.length - 2; i++) {
var c = (ppts[i].x + ppts[i + 1].x) / 2;
var d = (ppts[i].y + ppts[i + 1].y) / 2;
tmp_ctx.quadraticCurveTo(ppts[i].x, ppts[i].y, c, d);
}
// For the last 2 points
tmp_ctx.quadraticCurveTo(
ppts[i].x,
ppts[i].y,
ppts[i + 1].x,
ppts[i + 1].y
);
tmp_ctx.stroke();
};
};
第二个问题是在IE和fireFox中无法绘制. IE/fireFox的兼容性修补程序可以是什么?
The second problem is that in IE and fireFox, drawing is not possible. What can be the compatibility fix for IE/fireFox?
推荐答案
您不太可能丢失"任何mousemove事件.
每个操作系统都会调节(限制)每秒发出多少mousemove事件.因此,快速移动鼠标会导致mousemove事件之间的距离更大(分辨率更低).没有解决方法可以每秒获得更多的mousemove点.
Each operating system regulates (limits) how many mousemove events per second are emitted. So moving the mouse fast will cause more distance (less resolution) between mousemove events. There is no workaround to get more mousemove points per second.
您似乎正在捕获要创建样条线的点.如果是这样,Stackoverflow的Ken Fyrstenberg创建了一个不错的脚本,当喂入一组点时将创建一个样条曲线.您可以放松Ken样条曲线上的张力,这会使您的样条曲线相对于航路点变得更加平滑.松开张力会减少鼠标移动的航路点少于预期的影响.
It looks like you are capturing points to create a spline. If so, Stackoverflow's Ken Fyrstenberg has created a nice script that will create a spline when fed a set of points. You can loosen the tension on Ken's spline which will cause your spline to become more smoothed relative to the waypoints. Loosening the tension will reduce the effects of having fewer than desired mousemove waypoints.
如何使用javascript HTML5 canvas通过N个点绘制平滑曲线?
以跨浏览器兼容的方式捕获鼠标事件...
以下是用于捕获跨浏览器的鼠标拖动事件的模板:
Here's a template for capturing mouse drag events in across browsers:
window.onload=function(){
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var BB,BBoffsetX,BBoffsetY;
setBB();
// a flag indicating the mouse is being dragged
var isDown=false;
// an array of points accumulated during mouse dragging
var ppts=[];
// listen for mouse events
canvas.onmousedown=handleMousedown;
canvas.onmousemove=handleMousemove;
canvas.onmouseup=handleMouseup;
canvas.onmouseout=handleMouseup;
// recalculate the canvas offset if the window is scrolled
window.onscroll=function(e){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
function handleMousedown(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// get the mouse position relative to the canvas
var mouseX=e.clientX-BBoffsetX;
var mouseY=e.clientY-BBoffsetY;
// start a new ppts array
ppts=[];
// set the mouse-is-down flag
isDown=true;
}
function handleMouseup(e){
// if the mouse isn't being dragged, just return
if(!isDown){return;}
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// clear the mouse-is-down flag
isDown=false;
// get the mouse position relative to the canvas
var mouseX=e.clientX-BBoffsetX;
var mouseY=e.clientY-BBoffsetY;
// add this point to ppts
ppts.push({x:mouseX,y:mouseY});
alert('You have accumulated '+ppts.length+' points.');
}
function handleMousemove(e){
// if the mouse isn't being dragged, just return
if(!isDown){return;}
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// get the mouse position relative to the canvas
var mouseX=e.clientX-BBoffsetX;
var mouseY=e.clientY-BBoffsetY;
// add this point to ppts
ppts.push({x:mouseX,y:mouseY});
}
// calculate the canvas offset
function setBB(){
BB=canvas.getBoundingClientRect();
BBoffsetX=BB.left;
BBoffsetY=BB.top;
}
}; // end window.onload;
body{ background-color: ivory; }
canvas{border:1px solid red;}
<h4>Drag mouse to accumulate ppts</h4>
<canvas id="canvas" width=300 height=300></canvas>
这篇关于HTML5/Js画布在快速移动时捕获鼠标坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!