在悬停时更新HTML5画布矩形?

use*_*406 11 html javascript html5 canvas

我有一些在画布上绘制矩形的代码,但是当我将鼠标悬停在它上面时,我希望该矩形能够改变颜色.

问题是我绘制矩形之后我不确定如何再次选择它来进行调整.

我想做的事:

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.rect(20,20,150,100);
ctx.stroke();

$('c.[rectangle]').hover(function(this){
    this.fillStyle = 'red';
    this.fill();
});
Run Code Online (Sandbox Code Playgroud)

小智 26

你不能用画布开箱即用.Canvas只是一个位图,因此悬停逻辑必须手动实现.

方法如下:

  • 将所需的所有矩形存储为简单对象
  • 对于canvas元素上的每个鼠标移动:
    • 获得鼠标位置
    • 遍历对象列表
    • 使用isPointInPath()来检测"悬停"
    • 重绘两个州

var canvas = document.querySelector("canvas"),
    ctx = canvas.getContext("2d"),
    rects = [
        {x: 10, y: 10, w: 200, h: 50},
        {x: 50, y: 70, w: 150, h: 30}    // etc.
    ], i = 0, r;

// render initial rects.
while(r = rects[i++]) ctx.rect(r.x, r.y, r.w, r.h);
ctx.fillStyle = "blue"; ctx.fill();

canvas.onmousemove = function(e) {

  // important: correct mouse position:
  var rect = this.getBoundingClientRect(),
      x = e.clientX - rect.left,
      y = e.clientY - rect.top,
      i = 0, r;
  
  ctx.clearRect(0, 0, canvas.width, canvas.height); // for demo
   
  while(r = rects[i++]) {
    // add a single rect to path:
    ctx.beginPath();
    ctx.rect(r.x, r.y, r.w, r.h);    
    
    // check if we hover it, fill red, if not fill it blue
    ctx.fillStyle = ctx.isPointInPath(x, y) ? "red" : "blue";
    ctx.fill();
  }

};
Run Code Online (Sandbox Code Playgroud)
<canvas/>
Run Code Online (Sandbox Code Playgroud)


Hyd*_*per 8

这是一个基于@ K3N答案的稳定代码.他的代码的基本问题是因为当一个盒子在另一个盒子之上时,两个盒子可能同时被鼠标悬停.我的回答完美地解决了在'ASC'循环中添加'DESC'的问题.

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d");

var map = [
    {x: 20, y: 20, w: 60, h: 60},
    {x: 30, y: 50, w: 76, h: 60}
];

var hover = false, id;
var _i, _b;
function renderMap() {
    for(_i = 0; _b = map[_i]; _i ++) {
        ctx.fillStyle = (hover && id === _i) ? "red" : "blue";
        ctx.fillRect(_b.x, _b.y, _b.w, _b.h);
    }
}
// Render everything
renderMap();
canvas.onmousemove = function(e) {
    // Get the current mouse position
    var r = canvas.getBoundingClientRect(),
        x = e.clientX - r.left, y = e.clientY - r.top;
    hover = false;

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    for(var i = map.length - 1, b; b = map[i]; i--) {
        if(x >= b.x && x <= b.x + b.w &&
           y >= b.y && y <= b.y + b.h) {
            // The mouse honestly hits the rect
            hover = true;
            id = i;
            break;
        }
    }
    // Draw the rectangles by Z (ASC)
    renderMap();
}
Run Code Online (Sandbox Code Playgroud)
<canvas id="canvas"></canvas>
Run Code Online (Sandbox Code Playgroud)