如何使用画布和javascript同时绘制线条在鼠标指针顶部显示x和y坐标

Posted

技术标签:

【中文标题】如何使用画布和javascript同时绘制线条在鼠标指针顶部显示x和y坐标【英文标题】:how to draw lines simultaneously show x & y coordinators on top of mouse pointer using canvas and javascript 【发布时间】:2020-12-07 13:10:28 【问题描述】:

在 mouseDown 时画线,同时在鼠标指针顶部显示 x 和 y 坐标,而 MouseMove 使用画布和 javascript

这里 x 和 y 协调器在 MouseMove 时不断地在鼠标指针上绘制。然后我无法在 MouseDown 时画线,因为我使用的是 ctxTemp.clearRect(0,0,canvasTemp.width,canvasTemp.height);

如果我不使用 ctxTemp.clearRect(0,0,canvasTemp.width,canvasTemp.height);然后 x & y 协调器在 MouseMove 时不断地在鼠标指针上绘制。

先谢谢了。

【问题讨论】:

【参考方案1】:

双缓冲

在创建内容时在画布上呈现附加指南(坐标、小部件等)是一项常见任务。

使用单个画布会出现问题,因为您通过清除或仅绘制指南来覆盖内容。

解决方案是使用额外(或更多)画布将内容与指南分开。

示例

该示例显示了这是如何完成的。

创建第二个画布调用drawing。它与页面上画布的大小相匹配。

鼠标将笔划绘制到第二个画布上。

update 主函数将第二个画布绘制到主画布上,然后将鼠标位置绘制在其上方的框中。

由于您不能在画布外绘制,因此在绘制鼠标位置时需要一些额外的代码来防止它超出画布。

requestAnimationFrame(update);
const ctx = canvas.getContext("2d");
var w = canvas.width, h = canvas.height;
const drawing = createImage(w, h); // create canvas to hold drawing
const pointQueue = [];             // holds points when mouse button down
drawing.ctx.lineWidth = 4;
drawing.ctx.strokeStyle = "#F00";
drawing.ctx.lineJoin = "round";
drawing.ctx.lineCap = "round";
ctx.font = "16px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
/* add mouse listeners */
const bounds = canvas.getBoundingClientRect();
const mouse = x: 0, y: 0, button: false, events = ["down", "up", "move"];
events.forEach(name => document.addEventListener("mouse" + name, mouseEvents));
            
function drawMousePos(ctx) 
    const text = "X: " + mouse.x.toFixed(0) + " Y: " + mouse.y.toFixed(0);
    const width = ctx.measureText(text).width + 8;
    var x = mouse.x, y = mouse.y - 18;
    if (x + width / 2 > w)  x = w - width / 2 
    if (x - width / 2 < 0)  x = width / 2 
    if (y - 10  < 0)  y = 10 
    if (y + 10  > h)  y = h - 10 
    ctx.fillStyle = "#EEC8";
    ctx.fillRect(x - width / 2, y - 12, width , 20);
    ctx.strokeRect(x - width / 2, y - 12, width, 20);
    ctx.fillStyle = "#000C";
    ctx.fillText(text, x, y);

function drawPen(ctx) 
    if (pointQueue.length >= 2) 
        ctx.beginPath();
        ctx.moveTo(...pointQueue.shift());
        while (pointQueue.length > (mouse.button ? 1 : 0))  ctx.lineTo(...pointQueue.shift()) 
        pointQueue.length && ctx.lineTo(...pointQueue[0]);
        ctx.stroke();
    

function update()
    if (pointQueue.length) 
        drawPen(drawing.ctx);        
        ctx.clearRect(0, 0, w, h);
        ctx.drawImage(drawing, 0, 0);
        pointQueue.length && drawMousePos(ctx);
        canvas.style.cursor = "none";
     else  canvas.style.cursor = "crosshair" 
    requestAnimationFrame(update);

function createImage(w, h)
    const can = document.createElement("canvas");
    can.width = w;
    can.height = h;
    can.ctx = can.getContext("2d");
    return can;

function mouseEvents(e)
    mouse.x = e.pageX - bounds.left - 2;  // offset by 2 pixels for canvas border
    mouse.y = e.pageY - bounds.top - 2;
    if (e.type === "mousedown")  mouse.button = true  
    if (mouse.button)  pointQueue.push([mouse.x , mouse.y]) 
    if (e.type === "mouseup")  mouse.button = false 
canvas  
    border : 2px solid black; 
    cursor: crosshair;
Click drag mouse to draw<br>
<canvas id="canvas"  ></canvas>

【讨论】:

它非常有用,但目前 x&y 坐标在 mouseDown + mouseMove 之后显示。你能在初始 mouseMove 时修改并帮助我制作 x 和 y 坐标吗?【参考方案2】:

您可以尝试将 div 或 span 绑定到您的鼠标,并将其附加一个 eventListener,例如“mousemove”,在这个 div 中您可以有两个 span,例如

<div id='mouseCoord" style="position: absolute; top:0,left:0">
   <span id='mouseX'><span>
   <span id='mouseY'><span>
</div> 

div #mouseCoord 会有一个绝对位置,在鼠标移动时,你可以更新他的上/左位置

const mouseDiv = document.getElementById('mouseCoord')
const mouseX = document.getElementById('mouseX')
const mouseY = document.getElementById('mouseY')
mouseDiv.addEventListener('mousemove', e => 
  mouseDiv.setAttribute('style', `left: $e.offsetX;top: $e.offsetY`)
  mouseY.innerText = `y: $e.offsetY`
  mouseY.innerText = `x: $e.offsetX`
)

有了这个,您可以添加一些鼠标事件来控制何时显示坐标,例如仅在鼠标移动时等...

希望对你有帮助

【讨论】:

以上是关于如何使用画布和javascript同时绘制线条在鼠标指针顶部显示x和y坐标的主要内容,如果未能解决你的问题,请参考以下文章

如何在画布上动画绘制线条

在画布 (HTML5) 上绘制好看的(如在 Flash 中)线条 - 可能吗?

如何使用javascript HTML5画布通过N个点绘制平滑曲线?

如何在html5画布中逐步绘制线条动画

简单的 Qt 小部件来绘制线条和形状(如 tkinter 画布)?

绘制画布后淡出线条?