Why putting HTML5 canvas into the background doesn't work? - javascript

I am trying to put an HTML5 canvas as the background of my web page. I can't get it to work no matter what I do. Does anyone know how? This is my current attempt:
<!DOCTYPE html>
<html>
<head> <title> Test </title> </head>
<style>
#bgcanvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index = -1;
}
</style>
<script type="text/javascript">
function fillCanvas(){
var bg = document.getElementById("bgcanvas");
var ctx = bg.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 50, 50);
ctx = document.getElementById("screen").getContext("2d");
ctx.fillStyle = "#0000FF";
ctx.fillRect(0, 0, 500, 400);
}
</script>
<body onload="fillCanvas();">
<center>
<h1>Test Page</h1>
<canvas id="screen" width=720 height=480 style="background: black;">
Your browser sucks. Please upgrade.
</canvas>
</center>
</body>
<canvas id="bgcanvas" width=100 height=100> </canvas>
</html>
Thanks!

There are a few simple errors here you can adjust to make it work as pointed out in the various comments:
#bgcanvas {
/* ... rest not shown ... */
/* remove these unless you want the content to scale like an image:
width: 100%;
height: 100%;
*/
z-index: -1; /* change = to :. = is not supported in CSS for properties */
}
Move the canvas element inside the body tags:
...
<canvas id="bgcanvas" width=100 height=100> </canvas>
</body>
Tip: Increase the size to get better quality (you would currently scaling an "image" of 100x100 pixels to about the size of the window which will can give a poor result).
You can alternatively drop the CSS sizing and set the canvas size this way in your script before you draw anything to it:
var bg = document.getElementById("bgcanvas");
bg.width = window.innerWidth;
bg.height = window.innerHeight;

Related

Can anyone tell me why this isn't creating a square? [duplicate]

This question already has answers here:
Canvas is stretched when using CSS but normal with "width" / "height" properties
(10 answers)
Closed 3 years ago.
I'm following a tutorial to learn about canvas, and I'm unstuck pretty early on.
Here is the code:
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
context.lineWidth = 3;
context.strokeStyle = "blue";
context.lineJoin = "square";
context.strokeRect(10,10,200,200);
#canvas{
border: 1px solid black;
display: block;
width: 900px;
height: 600px;
margin: 0 auto;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>HTML Canvas</title>
<link rel="stylesheet" href="stylesheet.css" type="text/css">
</head>
<body>
<canvas id="canvas"></canvas>
<script src="script.js" type="text/javascript"></script>
</body>
</html>
It seems like it should be pretty straight-forward, but it's not doing what I expect. Can anyone advise?
The height and width of the canvas should initially be set in HTML or via DOM properties, not CSS to avoid resizing.
From MDN:
Indeed, the element has only two attributes, width and
height. These are both optional and can also be set using DOM
properties. When no width and height attributes are specified, the
canvas will initially be 300 pixels wide and 150 pixels high. The
element can be sized arbitrarily by CSS, but during rendering the
image is scaled to fit its layout size: if the CSS sizing doesn't
respect the ratio of the initial canvas, it will appear distorted.
Because of this, your square was also being resized to the same size of the canvas and could no longer fit completely within it.
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
context.lineWidth = 3;
context.strokeStyle = "blue";
context.lineJoin = "square";
context.strokeRect(10,10,200,200);
#canvas{
border: 1px solid black;
display: block;
margin: 0 auto;
}
<canvas id="canvas" height="600" width="900"></canvas>

Prevent scrolling on mobile on page with canvas

I've tried many solutions online, but for some reason, this page still moves around vertically when moving my touch on the canvas:
<html>
<head>
<style>
html, body {
overflow-x: hidden;
}
body {
background-color: lightgray;
position: relative;
}
body.noScroll {
overflow: hidden;
}
</style>
</head>
<body>
<canvas id="myCanvas" style="touch-action: none;" width="800" height="800"></canvas><br>
<script>
document.body.addEventListener("touchmove", getTouchPos)
var canvas = document.getElementById('myCanvas')
var context = canvas.getContext('2d')
context.fillStyle = "#000";
context.fillRect(0, 0, canvas.width, canvas.height);
function getTouchPos(evt) {
evt.preventDefault();
}
</script>
</body>
</html>
Tested on iOS Safari.
Have you found this post yet?
Disable scroll/swipe action for html canvas drawing on ios
It led to the following link. Looks like there are multiple events you have to account for. you have to reference your canvas as a dom element as well to evaluate the target
http://bencentra.com/code/2014/12/05/html5-canvas-touch-events.html

Wrong size of canvas when set by JavaScript [duplicate]

I was testing html5 canvas element, and wish my canvas to be full screen in the display area. But I found if I set the canvas height to window.innerHeight, the scroll bar will be shown up. I tried and found need to set the height to 5 pixel less, the scroll bar will disappear, but unfortunately it left a white border below the canvas. If it's a div element, everything is fine.
The code I'm using to test is:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script type="text/javascript">
function load() {
var o = document.getElementById('canvas');
if (o) {
o.width = window.innerWidth;
o.height = window.innerHeight - 5;
}
o = document.getElementById('div');
if (o) {
o.style.width = window.innerWidth + 'px';
o.style.height = window.innerHeight + 'px';
}
}
</script>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
body {
background-color: white;
}
#canvas {
background-color: blue;
}
#div {
background-color: green;
}
</style>
</head>
<body onload="load();">
<canvas id="canvas"></canvas>
<!--div id="div"></div-->
</body>
</html>
I've cleared the body margin and padding.
I test it on Chrome 8.0.552, and also it acts same on Firefox 3.6.13 but 4 pixel less is fine.
Anything I missed? Any suggestions will be really appreciated. Thanks a lot.
By default canvas, unlike div, is display: inline; so it gets set to vertical-align: baseline;. You can take either of the following approaches to make things naturally fill the window.innerHeight:
#canvas {
background-color: blue;
vertical-align: top;
}
Or:
#canvas {
background-color: blue;
display: block;
}

drawing to responsive canvas that is 100% width and height

I am trying to get a shape to follow the mouse cursor on a large canvas. This code isn't working as expected. How can I modify this to the relative canvas size if the canvas is 100% width / height of the screen?
Also, I am aware of requestanimationframe, but for the purpose of demonstrating this issue, please ignore it (I'm using it but its a complicated mess of timings that aren't related to this example).
Fiddle: https://jsfiddle.net/gs5a4z84/
CSS:
* { margin: 0; padding: 0;}
body, html { height:100%; }
canvas {
image-rendering: -moz-crisp-edges; /* Firefox */
image-rendering: pixelated; /* Chrome */
position:absolute;
width:100%;
height:100%;
}
HTML/JS:
<!DOCTYPE html>
<html>
<head>
<link href="main.css" rel="stylesheet"</link>
</head>
<body>
<div id="wrapper">
<canvas id="ctx" width="256" height="144"></canvas>
</div>
<script>
var mouseX, mouseY;
const WIDTH = 256;
const HEIGHT = 144;
var ctx = document.getElementById('ctx').getContext('2d');
ctx.canvas.addEventListener('mousemove', setMousePosition, false);
function setMousePosition(e) {
mouseX = e.clientX;
mouseY = e.clientY;
}
function drawCursor() {
ctx.clearRect(0,0,WIDTH,HEIGHT);
ctx.fillStyle = "#FF6A6A";
ctx.fillRect(mouseX, mouseY, 16, 16);
}
setInterval(function (){
drawCursor();
}, 40);
</script>
</body>
</html>
Thank you for any and all help.
If you use CSS width and height property for the canvas object, then you won't actually change how many pixels there are on the canvas, but how big it is. To fix your problem, set the canvas' width and height property using JavaScript:
JavaScript:
ctx.canvas.width = innerWidth;
ctx.canvas.height = innerHeight;
CSS:
body, canvas {
margin: 0;
padding: 0;
}

How to rerender (rather than resample) a canvas?

Chrome and Firefox handle the following code fine when rendered at 100%.
<!DOCTYPE html>
<html>
<head>
<script type="application/x-javascript">
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.arc(50,50,25,0,2*Math.PI);
ctx.stroke();
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="100" height="100">
<p>This example requires a browser that supports the
HTML5
<canvas> feature.</p>
</canvas>
</body>
</html>
But if someone magnifies my page a little, the canvas is sampled, not repainted. It's only a little ugly at 150%, but by the time the viewer reaches 300%, it will look very ugly:
How do I rewrite the code above so that the circle is repainted at the new magnification, not resampled?
This answer leads me to believe that it can be easily done. My attempt
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
</style>
<script type="application/x-javascript">
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
ctx.beginPath();
ctx.arc(ctx.canvas.width/2, ctx.canvas.height/2,
ctx.canvas.height/4,0,2*Math.PI);
ctx.stroke();
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas">
<p>This example requires a browser that supports the
HTML5
<canvas> feature.</p>
</canvas>
</body>
</html>
is no good. The circle is still resampled when the user magnifies. Can you do better?
(Chrome and Firefox behave differently when one magnifies. The effect I'm aiming for is for the circle to stay put with its center in the middle of the canvas and its radius a quarter of the window's height.)
Try doing the onload combined with the window resize event to redraw the canvas (zooming triggers the resize event):
window.addEventListener('resize', draw);
CANVAS REDRAWING
Example: http://jsfiddle.net/ksvyndwp/
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
ctx.beginPath();
ctx.arc(ctx.canvas.width/2, ctx.canvas.height/2,
ctx.canvas.height/4,0,2*Math.PI);
ctx.stroke();
}
}
draw();
window.addEventListener('resize', draw);
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
<canvas id="canvas">
<p>This example requires a browser that supports the
HTML5
<canvas> feature.</p>
</canvas>
If you're still worried about pixelization at higher zoom levels, I'm afraid there's nothing you can do about it directly on the canvas, because canvas' pixels scale with the window, and although you enter the sub-pixel rendering stage, there's nothing you can do to make it look better.
CSS SCALING
However, if you don't want to do it purely inside the canvas, you can do a simple CSS transformation that will make your circle look correctly on all zoom levels. Setting the width and the height to 100% will keep the canvas (as in canvas, the DOM element; not the actual canvas.width and canvas.height) the size of the window, so it's basically "immune" to zooming.
See it here (actually works much better when zooming the jsfiddle: http://jsfiddle.net/406h7xm0/ than the Stack Overflow iframe):
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
ctx.beginPath();
ctx.arc(ctx.canvas.width/2, ctx.canvas.height/2,
ctx.canvas.height/4,0,2*Math.PI);
ctx.stroke();
}
console.log(window.innerWidth);
}
draw();
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
canvas {
width: 100%;
height: 100%;
}
<canvas id="canvas"></canvas>
The final solution of what you're trying to do probably lies somewhere between the two approaches I've shown you.

Categories

Resources