Html5 / Js画布在快速移动时捕捉鼠标坐标

时间:2015-03-20 15:16:50

标签: javascript html5 canvas mouseevent

我有一个画布,我绘制一条曲线。 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的兼容性修补程序?

1 个答案:

答案 0 :(得分:1)

你不太可能&#34;失踪&#34;任何mousemove事件。

每个操作系统调节(限制)每秒发送的mousemove事件数。因此,快速移动鼠标将导致mousemove事件之间的距离更长(分辨率更低)。没有解决方法可以获得每秒更多的鼠标移动点数。

看起来您正在捕捉点以创建样条线。如果是这样,Stackoverflow的Ken Fyrstenberg已经创建了一个很好的脚本,它将在输入一组点时创建一个样条曲线。你可以放松Ken样条上的张力,这样可以使样条曲线相对于航点变得更加平滑。松开张力会减少使用少于预期的鼠标移动路点的影响。

how to draw smooth curve through N points using javascript HTML5 canvas?

以跨浏览器的方式捕获鼠标事件......

这是一个用于在不同浏览器中捕获鼠标拖动事件的模板:

&#13;
&#13;
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;
&#13;
body{ background-color: ivory; }
canvas{border:1px solid red;}
&#13;
<h4>Drag mouse to accumulate ppts</h4>
<canvas id="canvas" width=300 height=300></canvas>
&#13;
&#13;
&#13;