Текст и анимация вместе на холсте HTML5

У меня есть холст на основе анимации, который при наведении мыши анимирует капли дождя, а анимация останавливается при наведении мыши. У меня есть текстовое поле, которое при отправке должно отображать текст на холсте. Однако этот текст исчезает, когда я снова перемещаюсь и навожу курсор мыши. Я знаю, что холст перерисовывается при наведении курсора, но я не могу понять, как сделать так, чтобы текст оставался там, где он есть. Спасибо!

Я адаптировал код из приведенного здесь решения => Случайные изображения, падающие как дождь на холсте (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>

person stud91    schedule 06.12.2013    source источник


Ответы (2)


Каждый раз, когда вы перерисовываете холст, вам нужно перерисовывать текстовое поле, я лично переименовываю «clicked()» и вызываю его изнутри «draw()» (до или после капель в зависимости от того, хотите ли вы, чтобы он отображался выше или ниже )

Вам также придется удалить ctx.clearRect() из «clicked()», иначе он перезапишет дождь (если вы поместите его сверху)

Затем вам нужно будет отредактировать, как он был вызван, функция clicked() может установить логическую переменную, которая проверяется внутри функции рисования (и, если это правда, рисует текстовое поле)

Пример псевдокода:

var text = false
draw(){
    drawRain()
    if(text == true){drawText()}
}
clicked(){
    text = true
}

Затем, если вы хотите, чтобы текстовое поле было редактируемым, вы можете использовать переменные вместо фиксированных значений в drawText(), например.

Вне drawText()

fontVar = "36px Verdana";
fillColour = "yellow";
strokeColour = "green";

Внутри DrawText()

ctx.font=fontVar;
ctx.fillStyle=fillColour;
ctx.strokeStyle=strokeColour;
person DBS    schedule 06.12.2013
comment
Я думал об этом, но когда вы меняете сообщение (т.е. отправляете второе сообщение), оно смешивается с первым сообщением. Это единственная проблема. - person stud91; 06.12.2013
comment
Ах, так вы хотите, чтобы было видно несколько текстовых полей? и вы имеете в виду, что они перекрывают друг друга, когда вы этого не хотите? - person DBS; 06.12.2013
comment
Да, когда я отправляю второе сообщение, первое сообщение должно быть удалено и не перекрываться. - person stud91; 06.12.2013
comment
Способ, который я предложил, не должен позволять им перекрываться, если вы нарисуете их обоих с помощью одной и той же функции и просто отредактируете переменные, используемые в этой функции, он нарисует новое текстовое поле. Подождите секунду, я добавлю в ответ псевдокод. - person DBS; 06.12.2013
comment
Мы приближаемся. 1 проблема в том, что clicked() установил text=true, поэтому, когда я ввожу другой текст. Без нажатия кнопки отправки при наведении курсора мыши на холст новый текст заменяет предыдущий, поскольку текст является «истинным». - person stud91; 06.12.2013
comment
Кроме того, перекрытие удаляется только при наведении курсора мыши. Если я не делаю наведение мыши, то перекрытие существует. - person stud91; 06.12.2013
comment
Для текста, изменяющегося перед отправкой, не редактируйте переменные, пока не захотите, чтобы он изменился, сохраните новые значения в другом месте, а затем установите их при отправке. - person DBS; 06.12.2013
comment
и если они перекрываются до тех пор, пока вы не наведете курсор, то вы должны рисовать новое текстовое поле где-то за пределами функции рисования (поскольку каждый раз следует вызывать только один drawText(), а draw() должен перезаписывать все, что уже видно, учитывая, что вы применение фона) - person DBS; 06.12.2013
comment
Первая проблема решена. Второй вопрос = Да, конечно. Помните, что функция drawText() также вызывается, когда вы нажимаете кнопку отправки. Это вне метода draw(), который вызывается при наведении курсора мыши. - person stud91; 06.12.2013
comment
давайте продолжим это обсуждение в чате - person DBS; 06.12.2013

Ответ на этот вопрос кроется в укладке двух слоев полотна. Первый слой Canvas будет иметь фоновое изображение и эффект анимации. Второй слой поверх него будет рисовать текст. Примечание. Спасибо @DBS за поиск решения.

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

Как я могу сложить два одинаковых холсты друг на друга?

person stud91    schedule 06.12.2013