I'm drawing a grid on a JavaScript canvas on this canvas I also have a moving element so the Grid can be on/off with a button all is well apart from the speed of the moving element when grid is on it becomes extremely slow. I'm not really sure where am I going wrong. Can someone please give me some help. Thank you
HTML
<div>
<input type=button id="up" onClick=move_img(id); value='Up'>
<input type=button id="down" onClick=move_img(id); value='Down'>
<input type=button id="left" onClick=move_img(id); value='Left'>
<input type=button id="right" onClick=move_img(id); value='Right'>
<input type=button id="stop" onClick=move_img(id); value='Stop'>
<input type=button id="grid" onClick=gridOn(); value='Grid'>
<br>
<p></p>
</div>
JavaScript
var isGrid = new Boolean(false);
var canvas = document.getElementById("canvas");
b = canvas.getContext("2d");
var width = canvas.width = 600;
var height = canvas.height = 400;
document.body.appendChild(canvas);
b.fillStyle = "#F0F8FF";
b.fillRect(0, 0, canvas.width, canvas.height);
var posX = 10;
posY = 10;
x = 0;
y = 0;
setInterval(function () {
b.fillStyle = "#F0F8FF";
b.fillRect(0, 0, width, height);
posX = x;
posY = y;
if (posX > width - 20) {
x = 0;
posX = width - 20;
}
if (posX < 0) {
x = 0;
posX = 0;
}
if (posY > height - 20) {
y = 0;
posY = height - 20;
}
if (posY < 0) {
y = 0;
posY = 0;
}
b.fillStyle = "red";
b.fillRect(posX, posY, 20, 20);
/** Grid ***/
if(isGrid){
drawGrid();
}
/**************/
}, 5)
function move_img(id) {
switch (id) {
case "down":
moveDown();
break;
case "up":
moveUp();
break;
case "left":
moveLeft();
break;
case "right":
moveRight();
break;
case "stop":
moveStop();
break;
}
}
function moveDown(){
x = 0;
y = 1;
}
function moveUp(){
x = 0;
y = -1;
}
function moveLeft(){
x = -1;
y = 0;
}
function moveRight(){
x = 1;
y = 0;
}
function moveStop(){
x = 0;
y = 0;
}
function gridOn() {
if(isGrid){
isGrid = false;
}else{
isGrid = true;
}
}
function drawGrid(){
b.strokeStyle = 'black';
b.lineWidth = 0.5;
for(i = 0; i<= 600; i=i 40){
b.moveTo(i, 0);
b.lineTo(i, 600);
b.stroke();
}
for(j = 0; j<= 600; j=j 40){
b.moveTo(0, j);
b.lineTo(600, j);
b.stroke();
}
}
CodePudding user response:
You can use 2 canvas
with position absolute
. One for red box and another for Grid
. That will help you to move box without clearing grid.
Also, you can follow @reyno's advice that will help you to reduce some loops.
Also, you can make only one method move
and use it for all sides by passing x
and y
based on button. This will reduce the line of code.
See the Snippet below:
var isGrid = new Boolean(false);
var canvas = document.getElementById("canvas");
b = canvas.getContext("2d");
var gridCanvas = document.getElementById("grid-canvas");
bGrid = gridCanvas.getContext("2d");
var width = gridCanvas.width = 600;
var height = gridCanvas.height = 400;
canvas.width = width;
canvas.height = height;
//document.body.appendChild(canvas);
bGrid.fillStyle = "#F0F8FF";
bGrid.fillRect(0, 0, gridCanvas.width, gridCanvas.height);
b.fillRect(0, 0, gridCanvas.width, gridCanvas.height);
var posX = 10;
posY = 10;
x = 0;
y = 0;
let _interval = null;
drawImg();
if(isGrid){
drawGrid();
}
function drawImg(){
_interval = setInterval(function(){
/*b.fillStyle = "#F0F8FF";
b.fillRect(0, 0, width, height);*/
b.clearRect(0,0, width, height);
posX = x;
posY = y;
if (posX > width - 20) {
x = 0;
posX = width - 20;
}
if (posX < 0) {
x = 0;
posX = 0;
}
if (posY > height - 20) {
y = 0;
posY = height - 20;
}
if (posY < 0) {
y = 0;
posY = 0;
}
b.fillStyle = "red";
b.fillRect(posX, posY, 20, 20);
}, 1000/60)
}
function stopImg(){
clearInterval(_interval);
}
function move_img(id) {
switch (id) {
case "down":
move(0,1);
break;
case "up":
move(0,-1);
break;
case "left":
move(-1,0);
break;
case "right":
move(1,0);
break;
case "stop":
move(0,0);
break;
}
}
function move(_x,_y){
x = _x;
y = _y;
if(_x ==0 && _y==0){
stopImg();
}else{
drawImg();
}
}
/*function moveDown(){
x = 0;
y = 1;
}
function moveUp(){
x = 0;
y = -1;
}
function moveLeft(){
x = -1;
y = 0;
}
function moveRight(){
x = 1;
y = 0;
}
function moveStop(){
x = 0;
y = 0;
}*/
function gridOn() {
if(isGrid){
isGrid = false;
bGrid.clearRect(0,0, width, height);
bGrid.fillRect(0,0, width, height);
}else{
isGrid = true;
bGrid.fillRect(0,0, width, height);
drawGrid();
}
}
function drawGrid(){
bGrid.strokeStyle = 'black';
bGrid.lineWidth = 0.5;
for(i = 0; i<= 600; i=i 40){
bGrid.moveTo(i, 0);
bGrid.lineTo(i, 600);
bGrid.stroke();
bGrid.moveTo(0, i);
bGrid.lineTo(600, i);
bGrid.stroke();
}
/* for(j = 0; j<= 600; j=j 40){
b.moveTo(0, j);
b.lineTo(600, j);
b.stroke();
}*/
}
canvas{
position: absolute;
}
#canvas{
z-index: 1;
}
<div>
<input type=button id="up" onClick=move_img(id); value='Up'>
<input type=button id="down" onClick=move_img(id); value='Down'>
<input type=button id="left" onClick=move_img(id); value='Left'>
<input type=button id="right" onClick=move_img(id); value='Right'>
<input type=button id="stop" onClick=move_img(id); value='Stop'>
<input type=button id="grid" onClick=gridOn(); value='Grid'>
<br>
<p></p>
</div>
<canvas id="canvas"></canvas>
<canvas id="grid-canvas"></canvas>
You can also test it here