HTML5/Js画布在快速移动时捕获鼠标坐标 [英] Html5/Js canvas capturing mouse coords when it moves fast

查看:85
本文介绍了HTML5/Js画布在快速移动时捕获鼠标坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在画布上画曲线.将基于该曲线绘制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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆