Refresh HTML5 canvas rectangle when freezing?

I have a code that draws a rectangle on a canvas, but I want this rectangle to change color when I hover over it.

The problem is that after I drew the rectangle, I'm not sure how to select it again to complete the setup.

What I want to do:

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();
});
+8
source share
8 answers

You cannot do this out of the box with the canvas. A canvas is just a bitmap, so the hover logic must be done manually.

Here's how:

  • Save all the rectangles you want as a simple object
  • For each mouse move on the canvas element:
    • Get mouse position
    • 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();
  }

};
<canvas/>
Hide result
+22

@K3N. , , , . , "DESC" "ASC".

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();
}
<canvas id="canvas"></canvas>
Hide result
+5

    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");
    ctx.rect(20,20,150,100);
    ctx.stroke();
    
    $(c).hover(function(e){
        ctx.fillStyle = 'red';
        ctx.fill();
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<canvas id="myCanvas"/>
Hide result
+1

, JavaScript , . .

<!DOCTYPE html>
<html>
<body>

<canvas id="myCanvas" width="700" height="500" style="border:1px solid #c3c3c3;">
Your browser does not support the HTML5 canvas tag.
</canvas>

<script>
var myRect={x:150, y:75, w:50, h:50, color:"red"};
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = myRect.color;
ctx.fillRect(myRect.x, myRect.y, myRect.w, myRect.h);

c.addEventListener("mousemove", function(e){
if ((e.clientX>=myRect.x)&(e.clientX<=myRect.x+myRect.w)&(e.clientY>=myRect.y)&(e.clientY<=myRect.y+myRect.h)){
myRect.color = "green";}
else{
myRect.color = "red";}
updateCanvas();
}, false);


function updateCanvas(){
ctx.fillStyle = myRect.color;
ctx.fillRect(myRect.x, myRect.y, myRect.w, myRect.h);
}
</script>

</body>
</html>
+1

canvas.addEventListener

var canvas = document.getElementById('canvas0');
canvas.addEventListener('mouseover', function() { /*your code*/ }, false);

google chrome

+1

:

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

c.addEventListener("mouseover", doMouseOver, false);//added event to canvas

function doMouseOver(e){
    ctx.fillStyle = 'red';
    ctx.fill();
}

DEMO

0

, , , canvas.

, , , (- ). , - . , , .

, . /, , . , , (SAT) . , , .

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const width = canvas.width = window.innerWidth;
const height = canvas.height = window.innerHeight;
const cx = width / 2;
const cy = height / 2;
const twoPie = Math.PI * 2;
const points = []; // This will be the array we store our hover points in later

class Point {
  constructor(x, y, r) {
    this.x = x;
    this.y = y;
    this.r = r || 0;
  }
}

class HoverPoint extends Point {
  constructor(x, y, r, color, hoverColor) {
    super(x, y, r);
    this.color = color;
    this.hoverColor = hoverColor;
    this.hovered = false;
    this.path = new Path2D();
  }

  draw() {
    this.hovered ? ctx.fillStyle = this.hoverColor : ctx.fillStyle = this.color;
    this.path.arc(this.x, this.y, this.r, 0, twoPie);
    ctx.fill(this.path);
  }
}

class Cursor extends Point {
  constructor(x, y, r) {
    super(x, y, r);
  }

  collisionCheck(points) {
  // This is the method that will be called during the animate function that 
  // will check the cursors position against each of our objects in the points array.
    document.body.style.cursor = "default";
    points.forEach(point => {
      point.hovered = false;
      if (ctx.isPointInPath(point.path, this.x, this.y)) {
        document.body.style.cursor = "pointer";
        point.hovered = true;
      }
    });
  }
}

function createPoints() {
  // Create your points and add them to the points array.
  points.push(new HoverPoint(cx, cy, 100, 'red', 'coral'));
  points.push(new HoverPoint(cx + 250, cy - 100, 50, 'teal', 'skyBlue'));
  // ....
}

function update() {
  ctx.clearRect(0, 0, width, height);
  points.forEach(point => point.draw());
}

function animate(e) {
  const cursor = new Cursor(e.offsetX, e.offsetY);
  update();
  cursor.collisionCheck(points);
}

createPoints();
update();
canvas.onmousemove = animate;

, . , , , , ctx.IsPointInPath().

, , , ctx.IsPointInPath(). - , , .

...

class Cursor extends Point {
  constructor(x, y, r) {
    super(x, y, r);
  }

  collisionCheck(points) {
    document.body.style.cursor = "default";
    points.forEach(point => {
      let dx = point.x - this.x;
      let dy = point.y - this.y;
      let distance = Math.hypot(dx, dy);
      let dr = point.r + this.r;

      point.hovered = false;
      // If the distance between the two objects is less then their combined radius
      // then they must be touching.
      if (distance < dr) {
        document.body.style.cursor = "pointer";
        point.hovered = true;
      }
    });
  }
}

, ,

, , - . .

0

.

<html>

<body>
  <canvas id="myCanvas" width="1000" height="500" style="border:1px solid #d3d3d3;">
    Your browser does not support the HTML5 canvas tag.</canvas>
</body>

<script>
  var canvas = document.getElementById("myCanvas"),
    ctx = canvas.getContext("2d"),
    circle = [{
        x: 60,
        y: 50,
        r: 40,
      },
      {
        x: 100,
        y: 150,
        r: 50,
      } // etc.
    ];

  // render initial rects.
  for (var i = 0; i < circle.length; i++) {

    ctx.beginPath();
    ctx.arc(circle[i].x, circle[i].y, circle[i].r, 0, 2 * Math.PI);
    ctx.fillStyle = "blue";
    ctx.fill();
  }

  canvas.onmousemove = function(e) {
    var x = e.clientX,
      y = e.clientY,
      i = 0,
      r;

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

    for (let i = 0; i < circle.length; i++) {
      if ((x > circle[i].x - circle[i].r) && (y > circle[i].y - circle[i].r) && (x < circle[i].x + circle[i].r) && (y < circle[i].y + circle[i].r)) {


        ctx.beginPath();
        ctx.arc(circle[i].x, circle[i].y, circle[i].r, 0, 2 * Math.PI);
        ctx.fillStyle = "blue";
        ctx.fill();
        ctx.shadowBlur = 10;
        ctx.lineWidth = 3;
        ctx.strokeStyle = 'rgb(255,255,255)';
        ctx.shadowColor = 'grey';
        ctx.stroke();
        ctx.shadowColor = 'white';
        ctx.shadowBlur = 0;

      } else {

        ctx.beginPath();
        ctx.arc(circle[i].x, circle[i].y, circle[i].r, 0, 2 * Math.PI);
        ctx.fillStyle = "blue";
        ctx.fill();
        ctx.shadowColor = 'white';
        ctx.shadowBlur = 0;
      }

    }

  };
</script>

</html>
Hide result
0

All Articles