Been having issues with this for a couple days, not sure why the text I'm rendering on the canvas is flashing so much. I'm using the requestAnimationFrame() function, but its still flickering.
What I want to have happen is for the text to move smoothly and they remove themselves from the array when they move completely off screen.
var canvas = document.getElementById("myCanvas");
var c = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var w = canvas.width;
var h = canvas.height;
var texts = [];
window.addEventListener("load", init);
function init() {
draw();
mainLoop();
}
function mainLoop() {
texts.push(createText("wow", "blue"));
texts.push(createText("wow", "green"));
texts.push(createText("wow", "red"));
setTimeout(function() { mainLoop(); }, 100);
}
function Text(x, y, vx, vy, varText, theColor){
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.color = theColor;
this.draw = function() {
drawStroked(varText, this.x, this.y, this.color);
}
}
function drawStroked(text, x, y, color) {
c.font = "30px bold Comic Sans MS";
c.strokeStyle = 'black';
c.lineWidth = 8;
c.strokeText(text, x, y);
c.fillStyle = color;
c.fillText(text, x, y);
}
function createText(varText, color) {
var x = (Math.random() * w / 2 ) + w/4;
var y = (Math.random() * h / 2) + h/2;
var vx = (Math.random() * .5) - .25
var vy = -(Math.random() * 3) - 1
return new Text(x, y, vx, vy, varText, color);
}
function draw() {
c.clearRect(0, 0, c.canvas.width, c.canvas.height);
for(var i = 0;i < texts.length; i++) {
var currentText = texts[i];
currentText.x += currentText.vx;
currentText.y += currentText.vy;
currentText.draw();
if(currentText.x>w||currentText.x<0||currentText.y<10){
texts.splice(i, 1);
}
}
requestAnimationFrame(draw);
}
body {
margin: 0;
padding: 0;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<title>Game Screen</title>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
</html>
The flickering you are seeing results from your looping code, where you skip elements of the array when deleting elements (Element 3 needs to be deleted? You call splice(3, 1)
and then continue with the loop at index 4. Since the array shifts when you call splice
, you should process element 3 again).
The imho easiest way to fix this is to iterate backwards over the array. Please note that iterating backwards is less CPU cache efficient (because every array access leads to a cache miss), so another fix would be
if(currentText.x>w||currentText.x<0||currentText.y<10){
texts.splice(i--, 1); // decrement i after accessing and deleting
}
var canvas = document.getElementById("myCanvas");
var c = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var w = canvas.width;
var h = canvas.height;
var texts = [];
window.addEventListener("load", init);
function init() {
draw();
mainLoop();
}
function mainLoop() {
texts.push(createText("wow", "blue"));
texts.push(createText("wow", "green"));
texts.push(createText("wow", "red"));
setTimeout(function() { mainLoop(); }, 100);
}
function Text(x, y, vx, vy, varText, theColor){
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.color = theColor;
this.draw = function() {
drawStroked(varText, this.x, this.y, this.color);
}
}
function drawStroked(text, x, y, color) {
c.font = "30px bold Comic Sans MS";
c.strokeStyle = 'black';
c.lineWidth = 8;
c.strokeText(text, x, y);
c.fillStyle = color;
c.fillText(text, x, y);
}
function createText(varText, color) {
var x = (Math.random() * w / 2 ) + w/4;
var y = (Math.random() * h / 2) + h/2;
var vx = (Math.random() * .5) - .25
var vy = -(Math.random() * 3) - 1
return new Text(x, y, vx, vy, varText, color);
}
function draw() {
c.clearRect(0, 0, c.canvas.width, c.canvas.height);
for(var i = texts.length - 1;i >= 0; i--) {
var currentText = texts[i];
currentText.x += currentText.vx;
currentText.y += currentText.vy;
currentText.draw();
if(currentText.x>w||currentText.x<0||currentText.y<10){
texts.splice(i, 1);
}
}
requestAnimationFrame(draw);
}
body {
margin: 0;
padding: 0;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<title>Game Screen</title>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
</html>