如何使用javascript Canvas添加悬停功能



我有一个画布元素,它是一个由一堆图像组成的画布元素。我想为画布上的每个图像添加一个标签,但只希望当用户将鼠标悬停在正确的图像上时显示标签。

我已经设法显示了一些文本,但我无法弄清楚如何在鼠标悬停时显示它而不在鼠标离开时显示它。目前,我正在检查鼠标位置是否与点数组的鼠标位置匹配。如果是这样,它会添加文本。

canvas.addEventListener('mousemove', handleMouseMove.bind(this));

var handleMouseMove = function (e) {
    var mousePos = getSquare(canvas, e);
    var pos = points.filter((item => mousePos.x === item.x && mousePos.y === item.y));
    if (pos && pos.length) {
      context.fillStyle = "#ffffff";
      console.log(pos);
      context.fillText('Hello', pos[0].x, pos[0].y);
    } else {
      context.fillStyle = "#ffffff00";
      return;
    }
  };
  var getSquare = function (canvas, evt) {
    context.globalCompositeOperation = 'source-atop';
    var rect = canvas.getBoundingClientRect();
    return {
      x: 1 + (evt.clientX - rect.left) - (evt.clientX - rect.left) % 20,
      y: 1 + (evt.clientY - rect.top) - (evt.clientY - rect.top) % 20
    };
  };

从本质上讲,我希望"你好"出现,但只有当你将鼠标悬停在正确的位置上时。

我想您可以将画布保存到数据(也许是base64(。因此,当用户鼠标退出时,从存储的数据中重新绘制画布。

这是经典的交集,您必须将鼠标的 x 和 y 位置与画布上图像的 x、y、宽度和高度进行比较。如果它们相交,请显示标签。

你可以用一些相对简单的数学来做到这一点,或者使用isPointInPath函数来实现这一点。

一些超级简单的伪代码,有更好/更整洁的方法可以做到这一点;

image = x20,y50,w200,h100
mouse = x30,y40
if  mouse.x >= image.x
and mouse.x <= image.x + image.width
and mouse.y >= image.y
and mouse.y <= image.y + image.height {
    // mouse is over image
}

这是一个可以为图像使用多个提示的解决方案:

var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
var points = [
  {x: 10, y: 20}, 
  {x: 100, y: 50}
];
var images = [{
    src: 'https://via.placeholder.com/40', 
    tip: 'Hello',
    width: 40, height: 40
  }, {
    src: 'https://via.placeholder.com/80x50',
    tip: 'Another Image',
    width: 80, height: 50
  }
];
var drawImages = function () {
  context.clearRect(0,0,canvas.width,canvas.height);
  images.forEach(function (item, index) {
    if (item.img) {
      context.drawImage(item.img, points[index].x, points[index].y);
    } else {
      item.img = new Image();
      item.img.onload = function () {
        context.drawImage(item.img, points[index].x, points[index].y);
      }
      item.img.src = item.src;
    }
  }); 
};
drawImages();
var handleMouseMove = function (e) {
  drawImages();
  var mousePos = getSquare(canvas, e);
  var pos = points.filter((item, index) => (
    (mousePos.x >= item.x && mousePos.x <= item.x + images[index].width ) &&
    (mousePos.y >= item.y && mousePos.y <= item.y + images[index].height)
  ));
  if (pos && pos.length) {
    var index = points.indexOf(pos[0]);
    context.fillText(images[index].tip, mousePos.x, mousePos.y);
  }
};
var getSquare = function (canvas, evt) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: 1 + (evt.clientX - rect.left),
    y: 1 + (evt.clientY - rect.top)
  };
};
canvas.addEventListener('mousemove', handleMouseMove.bind(this));
canvas {border: 1px solid #000}
<canvas>No canvas support</canvas>

最新更新