javascripthtmlcanvashtml5-canvashtml5-animation

Text and animation together on HTML5 canvas


I have an animation based canvas that on mouseover animates rain droplets and the animation stops on mouseout. I have textbox which on submit should show text on canvas. However this text disappears when i moveout and mouseover again. I know that the canvas is redrawn on mouseover but i am unable to figure how to make the text remain where it is. Thanks!

I have adapted the code from the solution provided here => Random images falling like rain in canvas (Javascript)

Javascript

var ctx;
var imgBg;
var imgDrops;
var x = 0;
var y = 0;
var noOfDrops = 7;
var fallingDrops = [];
var intV;

imgBg = new Image();
imgBg.src = "image.jpg";
var canvas = document.getElementById('canvasRegn');
ctx = canvas.getContext('2d');
ctx.drawImage(imgBg,0,0,600,450); //Background

function draw() {
    ctx.drawImage(imgBg, 0, 0,600,450); //Background

    for (var i=0; i< noOfDrops; i++)
    {
    ctx.drawImage (fallingDrops[i].image, fallingDrops[i].x, fallingDrops[i].y); //The rain drop

    fallingDrops[i].y += fallingDrops[i].speed;
    fallingDrops[i+4].x += fallingDrops[i].speed-1;//Set the falling speed
    if (fallingDrops[i].y > 450) {  //Repeat the raindrop when it falls out of view
    fallingDrops[i].y = -120; //Account for the image size
    fallingDrops[i].x = Math.random() * 600;    //Make it appear randomly along the width    
    }

    }
}

function setup() {

    intV = setInterval(function(){draw()}, 36);
    for (var i = 0; i < noOfDrops; i++) {
        var fallingDr = new Object();
        fallingDr["image"] =  new Image();
        fallingDr.image.src = "Rain.svg";       
        fallingDr["x"] = Math.random() * 600;
        fallingDr["y"] = Math.random() * 5;
        fallingDr["speed"] = 3 + Math.random() * 5;
        fallingDrops.push(fallingDr);

        }
}
function start(){
setup();
}

function stop(){
    clearInterval(intV);
}

function clicked(){
    var x=document.getElementById("form_val");
    ctx.clearRect(0,0,600,400);
    ctx.font="36px Verdana";
    ctx.fillStyle="yellow";
    ctx.strokeStyle="green";
    ctx.lineWidth=2;
    ctx.strokeText(x.value,200,200);
    ctx.fillText(x.value,200,200);
}

HTML

<canvas id="canvasRegn" width="600" height="450"style="margin:10px;" onmouseover="start()" onmouseout="stop()">
</canvas>
<br>
<input type="text" name="fname" size="50" id="form_val">
<button id="submit" onclick="clicked()">Submit</button>

Solution

  • The answer to this question lies in the laying of two canvas layers. First Canvas layer will have the background image and the animation effect. Second layer on top of it will draw the Text. Note : Credit to @DBS for finding the solution.

    JavaScript:

    script type="text/javascript">
    var ctx;
    var ctx2
    var imgBg;
    var imgDrops;
    var x = 0;
    var y = 0;
    var noOfDrops = 20;
    var fallingDrops = [];
    var intV;
    fontVar ="36px Verdana";
    fillColour="yellow";
    strokeColour="green";
    
    imgBg = new Image();
    imgBg.src = "image.jpg";
    var canvas = document.getElementById('myCanvas');
    ctx = canvas.getContext('2d');
    ctx.drawImage(imgBg,0,0,600,400); //Background
    
    var canvas2 = document.getElementById('drawText');
    ctx2 = canvas2.getContext('2d');
    
    function drawing(){
    ctx.drawImage(imgBg,0,0,600,400); //Background
    }
    
    function draw() {
        ctx.drawImage(imgBg, 0, 0,600,400); //Background    
        for (var i=0; i< noOfDrops; i++)
        {
    
        ctx.drawImage (fallingDrops[i].image, fallingDrops[i].x, fallingDrops[i].y,35,35); //The rain drop
    
        fallingDrops[i].y += fallingDrops[i].speed;
        fallingDrops[i+7].x += fallingDrops[i].speed-1;//Set the falling speed
        if (fallingDrops[i].y > 400) {  //Repeat the raindrop when it falls out of view
            fallingDrops[i].y = -120; //Account for the image size
            fallingDrops[i].x = Math.random() * 600;    //Make it appear randomly along the width    
            }
        }       
    }
    
    
    function setup() {
    
        intV = setInterval(function(){draw()}, 36);
        for (var i = 0; i < noOfDrops; i++) {
            var fallingDr = new Object();
            fallingDr["image"] =  new Image();
            fallingDr.image.src = "Rain.svg";       
            fallingDr["x"] = Math.random() * 600;
            fallingDr["y"] = Math.random() * 5;
            fallingDr["speed"] = 3 + Math.random() * 5;
            fallingDrops.push(fallingDr);
    
            }
    }
    function start(){
    setup();
    }
    
    function stop(){
        clearInterval(intV);
    }
    
    function clicked(){
        z=document.getElementById("form_val");
        ctx2.clearRect(0,0,600,400);
        ctx2.font=fontVar;
        ctx2.fillStyle=fillColour;
        ctx2.strokeStyle=strokeColour;
        ctx2.lineWidth=2;
        ctx2.strokeText(z.value,200,200);
        ctx2.fillText(z.value,200,200);
    }
    
    </script>
    

    HTML

    <div class="wrapper">
    <canvas id="myCanvas" width="600" height="400" style="margin:1px;"></canvas>
    <canvas id="drawText" width="600" height="400" onmouseover="start()" onmouseout="stop()</canvas>
    </div>
    <br>
    Greeting Message: <input type="text" name="fname" size="50" id="form_val">
    <button id="submit" onclick="clicked()">Add this message</button>
    </div>
    

    CSS

    How can I stack two same-sized canvas on top of each other?