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 can I apply a CSS modification with a button [closed]

    How can I reduce the amount of vertical space between lines of text using CSS?

    If contains 'string' - set css “visibility:hidden;” - how to?

    How to align text and buttons next to canvas (WebGL + JavaScript + CSS)

    HTML table show last column using media queries

    How to add label to percentage bar in css and html?

    How to add / remove html elements and content based on the browsing device?

    How to create a table WITHOUT alternating row colors when using Blueprint CSS framework?

    How to have a background image wider than the content area of a website (without scrollbars)

    How to center a span element in CSS? [closed]

    jQuery - How to get elements height value and use it in another element via css code?

    How to align multiple columns in bootstrap 3 carousel?

    html, css - cursor - how to change default image for pointer

    How to add spacing between two rows of multiple divs each

    HTML/CSS Image Rollover/Animation, specific case with existing code, how to change animation?

    how to set button background such that it takes up height and width of parent div? what css property affects which dimension?

    How to create rounded edge panel in ExtJS 2.1

    How to solve position issue in ie7 using html and css?

    How to hide ads with media queries?

    How to select div with id nested in another div with class in css

    How to fit textarea exactly inside a div - CSS

    How to include a font .ttf using CSS?

    How to increase the distance between table columns in html?

    how to detect a url path with jquery and change css

    How to do auto slide for divs [closed]

    How to grows up a div height with a table that has your rows added dynamically?

    How to show image based on sort type in GridView

    How to get MathJax's HTML output just like Stackedit.io?

    How to make a pure css triangle which has a white center

    How to call an HTML css style in a computed text field