[英]Html5/Js canvas capturing mouse coords when it moves fast
我在畫布上繪制曲線。 基於該曲線繪制onmouseup線,並為其連接特定的x點。
問題是,如果快速移動鼠標 ,則不會捕獲其所有點。
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的兼容性修補程序可以是什么?
您不太可能“丟失”任何mousemove事件。
每個操作系統都會調節(限制)每秒發出多少mousemove事件。 因此,快速移動鼠標會導致mousemove事件之間的距離更大(分辨率更低)。 沒有解決方法可以每秒獲得更多的mousemove點。
您似乎正在捕獲點以創建樣條曲線。 如果是這樣,Stackoverflow的Ken Fyrstenberg創建了一個不錯的腳本,當喂入一組點時將創建一個樣條曲線。 您可以放松Ken樣條曲線上的張力,這會使您的樣條曲線相對於航路點變得更加平滑。 松開張力將減少具有少於所需的mousemove航路點的影響。
如何使用javascript HTML5 canvas通過N點繪制平滑曲線?
至於以跨瀏覽器兼容的方式捕獲鼠標事件...
這是用於捕獲跨瀏覽器的鼠標拖動事件的模板:
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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.