Canvas 帆布不';t跟随鼠标的实际位置

Canvas 帆布不';t跟随鼠标的实际位置,canvas,html5-canvas,Canvas,Html5 Canvas,我随后在convas中绘制了免费共享,前提是代码段不能正常工作,但当我尝试使用它时,它不能正常工作。我的意思是光标的位置和画布上的不同 截图 下面是代码片段 function init() { canvas = document.getElementById("whiteboard-canvas"); ctx = canvas.getContext("2d"); w = canvas.width; h = canvas.height;

我随后在convas中绘制了免费共享,前提是代码段不能正常工作,但当我尝试使用它时,它不能正常工作。我的意思是光标的位置和画布上的不同

截图

下面是代码片段


function init() {
  canvas = document.getElementById("whiteboard-canvas");
  ctx = canvas.getContext("2d");
  w = canvas.width;
  h = canvas.height;

  canvas.addEventListener(
    "mousemove",
    function (e) {
      findxy("move", e);
      console.log("on mouse move", e);
    },
    false
  );
#othere mouse event handler goes here..
}

function draw() {
  ctx.beginPath();
  ctx.moveTo(prevX, prevY);
  ctx.lineTo(currX, currY);
  ctx.strokeStyle = x;
  ctx.lineWidth = y;
  ctx.stroke();
  ctx.closePath();
}

function findxy(res, e) {
  if (res == "down") {
    prevX = currX;
    prevY = currY;
    currX = e.clientX - canvas.offsetLeft;;
    currY = e.clientY - canvas.offsetTop;;

    flag = true;
    dot_flag = true;
    if (dot_flag) {
      ctx.beginPath();
      ctx.fillStyle = x;
      ctx.fillRect(currX, currY, 2, 2);
      ctx.closePath();
      dot_flag = false;
    }
  }
  if (res == "up" || res == "out") {
    flag = false;
  }
  if (res == "move") {
    if (flag) {
      prevX = currX;
      prevY = currY;
      currX = e.clientX - canvas.offsetLeft;;
      currY = e.clientY - canvas.offsetTop;;
      draw();
    }
  }
}
我的代码片段与链接中的几乎相同。

CSS到画布像素坐标 画布分辨率(以像素为单位)和画布页面大小(以为单位)是独立的

使用2D API时,渲染是在画布像素(不是CSS像素)中完成的

鼠标事件保存坐标,因此不会始终直接转换为画布像素坐标

您可以使用它来获得画布的页面大小,该大小可用于从CSS像素缩放到画布像素

但是,在将CSS像素缩放为画布像素时,还必须考虑元素的填充和边框

注意在我的评论中,我谈到了设备像素比率。我对其用途的评估是错误的,在这种情况下不需要它

例子 该示例使用默认画布(300 x 150px),然后使用CSS规则将其缩放到页面,添加填充和边框(单位不是CSS像素)。画布也可以缩放,以便可以上下滚动

在整个页面和片段之间切换,以查看缩放如何影响示例

函数
getInnerRect
使用和获取页面上画布的边界(以CSS像素为单位)。从画布上左上角像素的左上角到最右下角像素的右下角

然后,draw函数使用内部rect(示例中名为
bounds
)计算比例(x,y)。然后偏移鼠标坐标并缩放它们以绘制到画布

  • 注意函数
    mouseEvent
    从和捕获鼠标坐标

  • 注意该功能与页面滚动位置相关。因此,当使用它的返回时,必须调整坐标以计算页面滚动位置。该示例使用和来执行此操作

  • 注意缩放和偏移也可以封装为二维变换。由于示例中的坐标仅在调整页面大小时才会更改,因此可以在调整页面大小时计算一次变换并将其应用于画布。因此,draw函数可以使用CSS像素直接渲染到画布。这使得示例中的代码更简单。(见第二段)

  • 注意由于变换将变换所有渲染大小,因此有必要计算变换的逆比例。在第二个示例中,这用于缩放线宽。如果不这样做,则呈现的线宽将随着页面大小的变化而变化

const ctx=canvas.getContext(“2d”);
var界;
常量鼠标={x:0,y:0,b:0,px:0,py:0};//p代表上一个按钮b
函数mouseEvent(事件){
mouse.px=mouse.x;
mouse.py=mouse.y;
mouse.x=event.pageX;
mouse.y=event.pageY;
如果(event.type==“mousedown”){
mouse.b=真;
canvas.classList.add(“绘图”);
}else if(event.type==“mouseup”| | event.type==“mouseout”){
mouse.b=假;
canvas.classList.remove(“绘图”);
}
draw();
}
addEventListener(“mousemove”,mouseEvent);
addEventListener(“mousedown”,mouseEvent);
addEventListener(“mouseup”,mouseEvent);
添加事件列表器(“mouseout”,mouseEvent);
常量CSSPx2Number=cssPx=>Number(cssPx.replace(“px”)和“);
函数getInnerRect(元素){
变量顶部、左侧、右侧、底部;
const bounds=element.getBoundingClientRect();
const canStyle=getComputedStyle(元素);
左=CSSPx2Number(canStyle.paddingLeft);
左+=CSSPx2Number(canStyle.borderLeftWidth);
top=CSSPx2Number(canStyle.paddingTop);
top+=CSSPx2Number(canStyle.borderTopWidth);
右=CSSPx2Number(canStyle.paddingRight);
右+=CSSPx2Number(canStyle.borderRightWidth);
bot=CSSPx2Number(canStyle.paddingBottom);
bot+=CSSPx2Number(canStyle.borderBottomWidth);
返回{
顶部:边界。顶部+顶部+滚动,
左:边界。左+左+滚动X,
底部:bounds.bottom+bot+scrollY,
右:边界。右+右+滚动X,
宽度:bounds.width-左-右,
高度:bounds.height-top-bot,
};
}
函数resizeEvent(){
bounds=getInnerRect(画布);
widthText.textContent=“画布页面大小:”+bounds.width.toFixed(1)+”by“+bounds.height.toFixed(1)+”px画布宽度:“+Canvas.width+”by“+Canvas.height+”px”;
ctx.lineWidth=3;
ctx.strokeStyle=“黑色”;
ctx.lineCap=ctx.lineJoin=“round”;
}
addEventListener(“调整大小”,resizeEvent);
resizeEvent();
函数绘图(){
如果(鼠标b){
const xScale=canvas.width/bounds.width;
const yScale=canvas.height/bounds.height;
常量x=(mouse.x-bounds.left)*xScale;
常数y=(mouse.y-bounds.top)*yScale;
常量px=(mouse.px-bounds.left)*xScale;
常量py=(mouse.py-bounds.top)*yScale;
ctx.beginPath();
ctx.lineTo(px,py);
ctx.lineTo(x,y);
ctx.stroke();
}
}
画布{
位置:绝对位置;
最高:5%;
左:10%;
宽度:80%;
身高:170%;
边框:1件纯蓝;
填充:1%;
光标:十字线;
}
.绘图{光标:无;}
.info{
位置:绝对位置;
字体系列:arial;
字体大小:x-small;
指针事件:无;
文本对齐:居中;
背景:白色;
边框:1px纯黑;
}
#宽度文本{
最高:2%;
左:20%;
宽度:60%;
}

首先,JS注释不是以
#
开头的-这是无效的,您可以