I'm trying to make a web game based on canvas and vanilla JS, but i'm struggling with displaying my canvas on mobile devices. On window.onload I'm assignin window height and width to the canvas dimensions. On PC it looks and works great but unfortunately while displayin on phone I have some bad white spaces under it or left site.
const CANVAS_ID = "game";
let canvas, canvasContext;
let bullets = [];
window.onload = function(){
resizeCanvas();
canvas = document.getElementById(CANVAS_ID);
canvasContext = canvas.getContext('2d');
resetGame();
document.getElementById('overlay').style.display = "none";
}
function resizeCanvas (){
let canvas = document.getElementById(CANVAS_ID);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
function resetGame (){
colorRect (0,0, canvas.width,canvas.height, "black");
canvasContext.font = "100px Arial";
//colorText("Welcome", 100, canvas.height/2, "white");
setInterval(drawGame, 1000/60);
setInterval(spawnBullet, 100);
}
Do you have any ideas what should I do?
Edit.
I have <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; user-scalable=0;"/> this tag.Is it correct?
Related
I have tried to create an HTML page with a full screen canvas and I can draw to this fine. If I create a second "off screen" canvas to draw on and display on the main canvas I do not see anything.
My code is:
var canvas;
var canvas_ctx;
var off_canvas = document.createElement('canvas');
var off_canvas_ctx;
init();
drawTree();
function init() {
canvas = document.getElementById('treeCanvas');
if (canvas.getContext) {
canvas_ctx = canvas.getContext("2d");
window.addEventListener('resize', resizeCanvas, false);
window.addEventListener('orientationchange', resizeCanvas, false);
resizeCanvas();
}
off_canvas.width = 5000;
off_canvas.height = 5000;
off_canvas_ctx = off_canvas.getContext('2d');
}
function resizeCanvas() {
var cWidth = window.innerWidth;
var cHeight = window.innerHeight - 3;
var imgData = canvas_ctx.getImageData(0, 0, cWidth, cHeight);
// Resize original canvas
canvas.width = cWidth;
canvas.height = cHeight;
// Copy back to resized canvas
canvas_ctx.putImageData(imgData, 0, 0);
}
function drawTree() {
canvas_ctx.fillStyle = "#FF0000";
canvas_ctx.fillRect(0, 0, 150, 75);
off_canvas_ctx.fillStyle = "#FF0000";
off_canvas_ctx.fillRect(0, 0, 150, 75);
resizeCanvas();
}
<div align="center">
<canvas id="treeCanvas" width="200" height="100">
Your browser does not support the canvas element.
</canvas>
</div>
My "drawTree()" function currently draws the same thing to both canvas contexts and then calls "resizeCanvas()" in order to update the display.
If I use the line
var imgData = canvas_ctx.getImageData(0, 0, cWidth, cHeight);
in "resizeCanvas()", the rectangle displays but if I try to use the image data from the off screen canvas with the line
var imgData = off_canvas_ctx.getImageData(0, 0, cWidth, cHeight);
then nothing is displayed. Can anyone see what I am doing wrong?
My mistake, in the "init()" function i was calling "resizeCanvas()" before i had got the context to the second canvas, this seemed to mess it up for the rest of the session.
canvas_ctx = canvas.getContext("2d");
off_canvas.width = 5000;
off_canvas.height = 5000;
off_canvas_ctx = off_canvas.getContext('2d');
Moving the block up appears to have fixed the problem.
I have a bird={} object where I define a draw function, however the image does not appear when called in the render function. Could anyone point me to what Im doing wrong? Thanks in advance.
EDIT: I have noticed the reason it does not always show up is because there are other sprites on the screen, and when I turn them off the bird always show up. Is there anything that can fix this?
bird = {
draw:function() {
var birdimg = new Image();
birdimg.onload = function() {
ctx.drawImage(birdimg, -20, height - 200);
}
birdimg.src = "//i.stack.imgur.com/nsZLM.png"; //"assets/bird.png";
}
};
function main() {
canvas = document.createElement("canvas");
//Set the width and height to the sizes of the browser
width = window.innerWidth;
height = window.innerHeight;
//Frames the game if the width is larger than 500
if(width >=500){
width = 320;
height = 480;
canvas.style.border = "1px solid #000";
evt = "mousedown";
}
//Sets the canvas sizes to the width and height variables
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
//Set the default state
currentstate = states.Splash;
document.body.appendChild(canvas);
render();
}
function render(){
//Adding bird
bird.draw();
//Loads sky.png
bgimg = new Image();
bgimg.onload = function() {
ctx.drawImage(bgimg,-20,height-200);
ctx.drawImage(bgimg,256,height-200);
}
bgimg.src = "assets/sky.png";
//Loads land img
landimg = new Image();
landimg.onload = function() {
ctx.drawImage(landimg,0,height-100);
}
landimg.src = "assets/land.png";
//Creates rectangle that colors background. THIS IS THE BOTTOM LAYER. WRITE CODE ABOVE
ctx.fillStyle="#4ec0ca";
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.stroke();
}
Following #K3N's suggestions here is a working example. Thanks #K3N for the guidance.
With these changes your code would look something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<script>
// declare vars so they are available outside of main()
var canvas,
ctx,
width,
height;
var bird = {
draw: function() {
var birdimg = new Image();
birdimg.src ="http://www.jqueryscript.net/images/Simplest-Responsive-jQuery-Image-Lightbox-Plugin-simple-lightbox.jpg";
birdimg.onload = function() {
ctx.drawImage(birdimg, -20, height - 200);
};
}
};
function main(){
canvas = document.createElement("canvas");
//Set the width and height to the sizes of the browser
width = window.innerWidth;
height = window.innerHeight;
//Frames the game if the width is larger than 500
if(width >=500){
width = 320;
height = 480;
canvas.style.border = "1px solid #000";
var evt = "mousedown";
}
//Sets the canvas sizes to the width and height variables
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
//Set the default state
// "states" is not defined so I'm commenting this out
// var currentstate = states.Splash;
document.body.appendChild(canvas);
render();
}
main();
function render(){
//Adding bird
bird.draw();
}
</script>
</body>
</html>
Live Demo
Hope this helps,
Nick Leoutsakos
I was wondering how I can make my canvas resize along with my browser window? As it is right now, using innerWidth and innerHeight, it will only size to the initial browser width and height. How do I make it expand with the browser?
Edit: Is there a way to do this without clearing the canvas?
JS
canvas.onmousemove = draw;
var ctx = canvas.getContext('2d');
var video = document.createElement("video");
video.setAttribute("src", "some_video.mp4");
video.autoplay = true;
var img2 = new Image;
img2.src = "some_image.png";
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
function draw(e){
var rect = canvas.getBoundingClientRect();
var x = e.clientX-rect.left-img2.width/2;
var y = e.clientY-rect.top-img2.height/2;
ctx.drawImage(video, x, y, 830, 644);
ctx.drawImage(img2, x, y, img2.width, img2.height);
}
Use it on resize
$(window).resize(function(){
// Place your code here which sets the width and height of canvas.
});
I am trying to use waveform.js found on http://www.waveformjs.org to draw waveforms of SoundCloud tracks. It hasn't been working so I've stripped down waveform.js to a bare bones form that attempts to draw a fillRect in a newly created canvas element through a Waveform object. The canvas element is successfully created but the fillRect does not appear. I've contrasted this to the direct creation of a canvas element and fillRect, which both work.
Here is the HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Sample document</title>
</head>
<body>
<div id="example1"></div>
<hr>
<div id="example2"></div>
</body>
<script src="waveform.js"></script>
<script src="script.js"></script>
</html>
Here is script.js:
var canvas, container;
// Creating canvas element and rect in example1
canvas = document.createElement("canvas");
canvas.setAttribute("id", "canvas");
container = document.getElementById("example1");
container.appendChild(canvas);
canvas.width = container.clientWidth;
canvas.height = container.clientHeight;
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
ctx.fillRect(20,20,50,100);
// Both created successfully
// Creating canvas element and rect in example2, through waveform object
var waveform = new Waveform({
container: document.getElementById("example2")
});
// Canvas element created successfully, no rectangle
Here is waveform.js:
(function() {
var Waveform;
window.Waveform = Waveform = (function() {
Waveform.name = 'Waveform';
function Waveform(options) {
this.container = options.container;
this.canvas = this.createCanvas(this.container, this.container.clientWidth, this.container.clientHeight);
this.context = this.canvas.getContext("2d");
this.width = parseInt(this.context.canvas.width, 10);
this.height = parseInt(this.context.canvas.height, 10);
this.makeRect();
};
Waveform.prototype.createCanvas = function(container, width, height) {
var canvas;
canvas = document.createElement("canvas");
canvas.setAttribute("id", "wfCanvas");
container.appendChild(canvas);
canvas.width = width;
canvas.height = height;
return canvas;
};
Waveform.prototype.makeRect = function() {
var wfCanvas = document.getElementById("wfCanvas");
var ctx = wfCanvas.getContext("2d");
ctx.fillRect(20,20,50,100);
}
return Waveform;
})();
}).call(this);
Bruh you're way over doing it.
Just be sure that the container you are applying the waveform to has PIXEL DIMENSIONS defined as either css or inline.
I have been trying to insert a canvas on top of some pages, but for some pages it doesn't work. It seems to be me that there is something clearing all canvases on the page, but I couldn't find any calls to .clearRect anywhere in the code on the page.
canvas = document.createElement('canvas');
canvas.width = document.width;
canvas.height = document.height;
canvas.style['z-index'] = 999;
canvas.style.position = 'absolute';
canvas.style.top = 0;
canvas.style.left = 0;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 1000, 1000);
A page with the problem is: http://www.nrk.no/sognogfjordane/helse-forde-har-ikkje-full-oversikt-1.11166801
If you run the same code on this page it should work. Expected result is a huge black square on the page.
I don't understand how a script can block the use of an inserted canvas on the page.
I am using Chrome.
* EDIT *
The problem is not that I use the deprecated document.width/heightcalls, but that I wasn't aware that canvas has a maximum size: Maximum size of a <canvas> element
Because document.width and document.height are undefined, so your canvas width and height are 0 and 0.
Instead try something like:
canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style['z-index'] = 999;
canvas.style.position = 'absolute';
canvas.style.top = 0;
canvas.style.left = 0;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 1000, 1000);
And you'll see it just fine.
See notes on the MDN. Specifically:
Starting in Gecko 6.0, document.width is no longer supported. Instead, use document.body.clientWidth.
Please look into the demo.
canvas = document.createElement('canvas');
canvas.width = document.width;
canvas.height = document.height;
canvas.style['z-index'] = 999;
canvas.style.position = 'absolute';
canvas.style.top = 0;
canvas.style.left = 0;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 1000, 1000);
I think this is what you needed. If you need something else then please exaplin or put your code in jsfiddle. Here in this demo it is creating canvas element.
I first thought Simon Sarris was correct, but in the end that didn't do what I wanted. What I want is a that covers the entire page.
I discovered through Maximum size of a <canvas> element that I was exceeding the limits of canvas.