## how to remove one canvas element from displaying on top of another canvas element

Tags: javascript,css,html5-canvas,popup-balloons

### Problem :

I have 2 canvases. One, the main canvas. Upon which all is drawn, Second, the speech bubble canvas (balloon). Which displays information about specific regions on my main canvas upon client clicks.

I was playing around with my canvas after introducing the speech bubble and came across an issue.

This is a simple code that shows how the speech bubble is introduced:-

http://jsfiddle.net/m1erickson/AJvkN/

My canvas is a timeline, and is scrollable; has historical events plotted on it. Once a user clicks on an event a speech bubble appears.

Now what I don't want to happen is, when a client clicks on the canvas, a speech bubble appears and then scrolls, the speech bubble moves to a new position on the scrolled image, however still showing information about the previous location.

For this we have the hideballoon () which assigns css property left : -200. However this still causes inconsistencies. For example if I drag the canvas from left to right, the balloon doesn't disappear with the scroll, but reappears in a new position.

there is a .remove() function $("#balloon").remove() http://api.jquery.com/remove/ This successfully removes the balloon however, the issue with this is:- it removes the balloon completely, and no future clicks will pop up any more speech bubbles. This is not what I want. I want something dynamic. Click on event >> speech bubble appears >> scroll canvas >> speech bubble disappears >> click on canvas >> speech bubble pertaining to new click appears back >> and so on and so forth. ### Solution : [Edited] Use .show() and .hide() to keep the balloon out of your way when its not needed When the user scrolls the window then just hide the balloon. I assume you're scrolling the window instead of the canvas. If you're scrolling the canvas, just use$("#canvas").scroll( ... ) instead.

So when you need the balloon:

        // move the balloon canvas to the target
$("#balloon").css({left:offsetX+X, top:offsetY+Y}); // and show it$("#balloon").show();


And hide the balloon when the user clicks on it or when the window scrolls:

    // listen for clicks on the balloon and then hide the balloon
$("#balloon").click(function(e){$("#balloon").hide(); });

// listen for scrolls and then hide the balloon
$(window).scroll(function(e){$("#balloon").hide();
});


Here’s working sample code and a Fiddle: http://jsfiddle.net/m1erickson/uWHkv/

<!doctype html>
<html>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
#canvas{border:1px solid red;}
#balloon{ position:absolute; left:-200px; }
</style>

<script>
$(function(){ // get reference to our drawing canvas var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); // get reference to our balloon canvas var balloon=document.getElementById("balloon"); var popCtx=balloon.getContext("2d"); // get the position of canvas relative to window var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;

// define some targets and their basic info
var count=1;
var circles=[];
for(var x=50;x<1900;x+=50){
circles.push({
color:"blue",
info:"I'm #"+(count++)});
}

// draw the target circles on the canvas
ctx.fillStyle="yellow";
ctx.font="16px verdana";
for(var i=0;i<circles.length;i++){
drawCircle(circles[i]);
ctx.beginPath();
ctx.fillText(i+1,circles[i].x-8,circles[i].y+5);
}

// listen for clicks on the canvas and show the balloon
$("#canvas").click(function(e){ // get the mouseclick position mouseX=parseInt(e.clientX-offsetX); mouseY=parseInt(e.clientY-offsetY); // account for the window scrolling var scrollX=$(window).scrollLeft();
var scrollY=$(window).scrollTop(); // see if we clicked on any targets for(var i=0;i<circles.length;i++){ var circle=circles[i]; var dx=(circle.x-scrollX)-mouseX; var dy=(circle.y-scrollY)-mouseY; var radius=circle.radius; // true if we clicked in the target circle if(dx*dx+dy*dy<=radius*radius){ drawBalloon(circles[i].x+radius,circles[i].y-100,circles[i].info); } } }); // listen for clicks on the balloon and then hide the balloon$("#balloon").click(function(e){ $("#balloon").hide(); }); // listen for scrolls and then hide the balloon$(window).scroll(function(e){
$("#balloon").hide(); }); function drawCircle(circle){ ctx.save(); ctx.beginPath(); ctx.fillStyle=circle.color; ctx.strokeStyle="black"; ctx.lineWidth=3; ctx.arc(circle.x,circle.y,circle.radius,0,Math.PI*2,false); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.restore(); } function drawBalloon(X,Y,theInfo){ popCtx.save(); popCtx.fillStyle="#FD0"; popCtx.strokeStyle="#000"; // draw the balloon popCtx.beginPath(); popCtx.moveTo(52,02); popCtx.quadraticCurveTo(02,02,02,42); popCtx.quadraticCurveTo(02,77,27,77); popCtx.quadraticCurveTo(27,102,07,102); popCtx.quadraticCurveTo(37,102,42,77); popCtx.quadraticCurveTo(102,77,102,42); popCtx.quadraticCurveTo(102,02,52,02); popCtx.lineWidth=3; popCtx.stroke(); popCtx.fill(); // draw theInfo popCtx.font="10pt arial"; popCtx.fillStyle="black"; popCtx.fillText(theInfo,10,50); popCtx.restore(); // move the balloon canvas to the target$("#balloon").css({left:offsetX+X, top:offsetY+Y});
$("#balloon").show(); } }); // end$(function(){});
</script>

<body>
<canvas id="canvas" width=1950 height=300></canvas>
<canvas id="balloon" width=105 height=105></canvas>
</body>
</html>