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>
<head>
<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>
    body{ width:2000px; background-color: ivory; padding:10px;padding-top:100px; }
    #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({
            x:x,  y:120, radius:20,
            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>

</head>

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

    CSS Howto..

    How to avoid loading CSS file for ipad sized devices ('between' mobile and full-sized)?

    How Can I Hide *Only* the Button (Not Entire Element) for the Input Type File in a Django Form? [duplicate]

    How do I specify a css margin-top for foundation row div?

    How to debug html code for which css is being applied? [duplicate]

    How to change a div top margin without leaving a white space?

    How to detect if browser support specified css pseudo-class?

    How to remove a CSS class from a Wicket component?

    How to let an object not take up its natural width

    How to fill an HTML form with CSS?

    How to Vertically Center Images on a Line?

    How to set border's thickness in percentages?

    How do I place a small paragraph to the right in between a text article

    css: how to display prev and next links outside slider

    How do I make menu background even with the header in HTML/CSS

    How to display “Classic” fractions in CSS / Javascript

    How can I make this kind of a border?

    How to vertically align both image and text side by side in a div

    How to place Social media icons on right side of navbar

    How to correctly set the column widths on my HTML table?

    How to write CSS for parent DIV needing height dictated by child DIVs that are also anchored bottom?

    How to get CSS Variables working in Dart

    How to disable button using jquery in materialize css

    How to make css smaller?

    Are there limits to how tall/wide CSS Sprite-maps can be?

    How not to display / filter out special characters? (CSS or Javascript)

    Flexbox used for equal height, however it is ignoring column width in grid system

    Change image src for product “showoff”

    On textbox focus, how can you change the background color of the element prior to it with only CSS?

    How to move object into the screen from outside via jQuery transition

    How to use Custom Fonts using CSS?