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

时间:2019-06-05 09:42:27

标签: javascript canvas html5-canvas

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

我设法显示了一些文本,但是我想不出如何只在鼠标悬停时显示它而不在mouseleave上显示。目前,我正在检查鼠标位置是否与points数组的鼠标位置匹配。如果这样做,则会添加文本。

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
    };
  };

基本上,我希望显示“ Hello”,但仅当您将鼠标悬停在正确的位置上时。

3 个答案:

答案 0 :(得分:0)

这是经典的交集,您必须将鼠标的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
}

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

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>