简体   繁体   English

在Fabric.js画布上以鼠标坐标添加图像会导致图像位置偏移

[英]Adding image on Fabric.js canvas at mouse coords results in offset image position

I have a rather trivial example where I'm attempting to insert an image on a Fabric.js canvas with the image centered at the mouse coordinates. 我有一个非常简单的示例,其中我试图在Fabric.js画布上插入图像,并以鼠标坐标为中心。 The center of the cursor should be the exact center of the image. 光标的中心应该是图像的确切中心。

I calculate the center of the image by halving its width and height and apply them as offsets to the left and top coordinates of the canvas.Image I'm inserting. 我通过将图像的宽度和高度减半来计算图像的中心,并将它们作为偏移量应用于canvas.Imageleft坐标和top坐标。 Simple enough: 很简单:

// Coordinates from the mouse click event. 
// `x` and `y` are aliases for `clientX`, `clientY`, respectively
const x = event.e.x,
      y = event.e.y

image.set({
    left: x - (image.width / 2),
    top: y - (image.height / 2)
})

canvas.add(image);

When the image is added, it's not quite center. 添加图像后,它并不太中心。 In fact, there's a difference of 8 pixels on both x and y axes that I cannot account for. 实际上,我无法解释xy轴上有8个像素的差异。

This is the result: 结果如下:

图像的中心应在光标下方。

The center of the image should be under the cursor. 图像的中心应在光标下方。

If I manually set the offset to 28, the image is properly centered. 如果我手动将偏移设置为28,则图像将正确居中。 But since I cannot account for the 8 extra pixels, this hack is unacceptable. 但是由于我无法考虑额外的8个像素,因此这种破解是不可接受的。

居中

Working sample: 工作样本:

 const canvas = new fabric.Canvas('c', { width: 400, height: 150 }); // Add an image centered x & y at the exact point the user clicks. canvas.on('mouse:up', (opt) => { canvas.clear(); const x = opt.ex, y = opt.ey; fabric.Image.fromURL('https://i.imgur.com/htyNxF6.png', (image) => { /* Calculate the offset based on the image dimensions: This does not work as expected. A 40x40 image has ax/y offsets of 20. If we set the offset to 28, the image is centered at the cursor. Why 28? Check the "Apply ..." checkbox to see this in action. */ const offsetX = chkOffset.checked ? 28 : (image.width / 2), offsetY = chkOffset.checked ? 28 : (image.height / 2); const left = x - offsetX, top = y - offsetY; image.set({ left: left, top: top, stroke: 0, padding: 0, centeredScaling: true, hasControls: false, strokeWidth: 0, hasBorders: 0 }); canvas.add(image); writeDebug(`Mouse at: x=${x}, y=${y}; Image placed at: x=${left}, y=${top} Difference of ${Math.abs(left-x)}, ${Math.abs(top-y)}`); }); // Show coordinates on mouse move canvas.on('mouse:move', (opt) => { const x = opt.ex, y = opt.ey; writeDebug(`Mouse coordinates: x=${x}, y=${y}`); }); }); function writeDebug(message) { document.getElementById('debug').innerText = message; } 
 body { font-family: Consolas; } #c { border: 1px solid #ececec; box-shadow: 2px 2px 5px #c0c0c0; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.1.0/fabric.min.js"></script> <canvas id="c"></canvas> <label for="chkOffset"> <input type="checkbox" id="chkOffset" /> Apply 28px offset </label> <div id="debug">Click in the canvas to add the image</div> 

When I was adding sample code to my question, I stumbled upon the answer. 当我向问题中添加示例代码时,我偶然发现了答案。 I set the padding of every element to 10 using CSS ( * { padding: 10px } ) to make everything look better and upon doing so discovered that the offset gap had increased. 我使用CSS( * { padding: 10px } )将每个元素的填充设置为10,以使所有内容看起来更好,并发现偏移量增加了。

Getting mouse coordinates using MouseEvent.ex and MouseEvent.xy are the culprit. 罪魁祸首是使用MouseEvent.exMouseEvent.xy获取鼠标坐标。 I compared their values with MouseEvent.e.offsetX and MouseEvent.e.offsetY and found that the x and y values did not account for padding and margins. 我将它们的值与MouseEvent.e.offsetXMouseEvent.e.offsetY ,发现xy值未考虑填充和边距。

Using offsetX and offsetY seemed to do the trick. 使用offsetXoffsetY似乎可以解决问题。

It seems if you want to get relevant mouse coordinates in Fabric.js, using offsetX and offsetY is the best bet as it accounts for offsets caused by CSS. 看来,如果您想在Fabric.js中获取相关的鼠标坐标,则最好使用offsetXoffsetY ,因为它考虑了CSS引起的偏移。

 const canvas = new fabric.Canvas('c', { width: 400, height: 150 }); // Add an image centered x & y at the exact point the user clicks. canvas.on('mouse:up', (opt) => { canvas.clear(); // Use .offset instead: const x = opt.e.offsetX, y = opt.e.offsetY; fabric.Image.fromURL('https://i.imgur.com/htyNxF6.png', (image) => { const offsetX = (image.width / 2), offsetY = (image.height / 2); const left = x - offsetX, top = y - offsetY; image.set({ left: left, top: top, stroke: 0, padding: 0, centeredScaling: true, hasControls: false, strokeWidth: 0, hasBorders: 0 }); canvas.add(image); writeDebug(`Mouse at: x=${x}, y=${y}; Image placed at: x=${left}, y=${top} Difference of ${Math.abs(left-x)}, ${Math.abs(top-y)}`); }); // Show coordinates on mouse move canvas.on('mouse:move', (opt) => { const x = opt.e.offsetX, y = opt.e.offsetY; writeDebug(`Mouse coordinates: x=${x}, y=${y}`); }); }); function writeDebug(message) { document.getElementById('debug').innerText = message; } 
 body { font-family: Consolas; } #c { border: 1px solid #ececec; box-shadow: 2px 2px 5px #c0c0c0; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.1.0/fabric.min.js"></script> <canvas id="c"></canvas> <div id="debug">Click in the canvas to add the image</div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM