1

I am trying to show a tooltip by hovering the mouse on a circle inside a canvas. While the CSS is changing from hidden to visible by javaScript (saw that through chrome inspect), the tooltip is not showing up. Please help to sort this out. Thank you for your help.

const canvas = document.getElementById('flower');
const ctx = canvas.getContext('2d');

const circle2 = new Path2D();
                        circle2.arc(100, 100, 25, 0, 2 * Math.PI);
                        ctx.fillStyle = "red";
                        ctx.fill(circle2);
                        
canvas.addEventListener("mousemove", function(event2) {
                            if (ctx.isPointInPath(circle2, event2.clientX, event2.clientY)) {
                                showtext();
                            }
                        }); 
                        
function showtext(){
    document.getElementById("tooltiptext").style.visibility = 'visible';
}
html, body, div, canvas {
        width:  100%;
        height: 100%;
        margin: 0;
}
    .tooltip {
        position: relative;
        display: inline-block;
        border-bottom: 1px dotted black; 
    }
    .tooltip .tooltiptextstyle {
        visibility: hidden; 
        display: block;
        width: 120px;
        background-color: black;
        color: #fff;
        text-align: center;
        padding: 5px 0;
        border-radius: 6px;
        position: absolute;
        z-index: 1;
    }
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link type="text/css" href="style.css"/>
    <script type="text/typescript" src="main.ts"></script>
</head>
<body>
    <div id="design" class="design">
        <canvas id="flower">
            <div class="tooltip">
                <span id ="tooltiptext" class="tooltiptextstyle">blah</span>
            </div>
        </canvas>
    </div>
</body>
</html>
Nihar
  • 333
  • 1
  • 6
  • 18

3 Answers3

3

you need to move the .tooltip element out of the canvas element, otherwise it won't display.

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

// Create circle
const circle = new Path2D();
circle.arc(150, 75, 50, 0, 2 * Math.PI);
ctx.fillStyle = 'red';
ctx.fill(circle);

// Listen for mouse moves
canvas.addEventListener('mousemove', function(event) {
  // Check whether point is inside circle
  if (ctx.isPointInPath(circle, event.clientX, event.clientY)) {
    showtext();
  } else {
    hidetext();
  }
});

function showtext() {
  document.getElementById("tooltiptext").style.visibility = 'visible';
}

function hidetext() {
  document.getElementById("tooltiptext").style.visibility = 'hidden';
}
.tooltip {
  visibility: hidden;
  position: absolute;
  top: 20px; left: 20px;
}

body {
  margin: 0;
}
<canvas id="canvas"></canvas>

<div class="tooltip">
  <span id="tooltiptext" class="tooltiptextstyle">blah</span>
</div>
Barudar
  • 560
  • 4
  • 13
  • Thank you so much :). It is working but I had to use "position: absolute;" for ".tooltip" instead of "relative", like you did. – Nihar Oct 24 '19 at 18:22
3

There were two issues:

  1. The manner in which you were applying styles to your canvas were causing its display not to match its internal tracking of the position of the items it contained, so the if condition was not necessarily returning true when the cursor was over where the circle was appearing.
  2. A canvas cannot render and display contents.

As such, the below snippet shows a version of this that works. You'll need to figure out how to position things correctly, but it solves the immediate issue.

const canvas = document.getElementById('flower');
const ctx = canvas.getContext('2d');

const circle2 = new Path2D();
circle2.arc(100, 100, 25, 0, 2 * Math.PI);
ctx.fillStyle = "red";
ctx.fill(circle2);
                        
canvas.addEventListener("mousemove", function(event2) {
  if (ctx.isPointInPath(circle2, event2.clientX, event2.clientY)) {
    showtext();
  }
}); 
                        
function showtext(){
    document.getElementById("tooltiptext").style.visibility = 'visible';
}
html, body, div {
  width:  100%;
  height: 100%;
  margin: 0;
}
.tooltip {
    position: relative;
    display: inline-block;
    border-bottom: 1px dotted black; 
}
.tooltip .tooltiptextstyle {
    visibility: hidden; 
    display: block;
    width: 120px;
    background-color: black;
    color: #fff;
    text-align: center;
    padding: 5px 0;
    border-radius: 6px;
    position: absolute;
    z-index: 1;
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link type="text/css" href="style.css"/>
    <script type="text/typescript" src="main.ts"></script>
</head>
<body>
    <div id="design" class="design">
        <canvas id="flower">
        </canvas>
        <div class="tooltip">
          <span id ="tooltiptext" class="tooltiptextstyle">
            blah
          </span>
      </div>
    </div>
</body>
</html>
Alexander Nied
  • 12,804
  • 4
  • 25
  • 45
  • Thank you. This is working for a small canvas but when I have a big canvas like my window then it's showing outside because of the CSS. I had to change the CSS as you mentioned. – Nihar Oct 24 '19 at 18:24
  • @Nihar - Excellent-- glad that this was helpful for you. – Alexander Nied Oct 24 '19 at 18:40
1

The problem was that you set the width and height of the canvas as the 100% of the parent in the css. You need to set the canvas's width and height attribute instead.

html, body, div, canvas {
        width:  100%;
        height: 100%;
        margin: 0;
}
html, body, div {
        width:  100%;
        height: 100%;
        margin: 0;
}
<canvas id="canvas" width="200" height="200">