Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set HTML Canvas as page background

Tags:

html

css

I've made a JS animation that I want to be the background of my homepage: http://geotheory.co.uk/. But I'm quite new to web development and unclear how to stop the canvas element being an 'inline' object on the page and set it behind other HTML elements. Very grateful for advice. The HTML is:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>geotheory.co.uk</title>
    <style>
        canvas:focus{outline:none;}
        * {
        margin: 0;
        padding: 0;
        }
        h1 {color:#fff;}
        p {color:#fff;}
    </style>

</head>
<body  id="home" bgcolor="black">
    <!-- style="overflow:hidden;" -->
    <h1>Heading</h1>
    <p>paragraph 1</p>
    <p>paragraph 2</p>
    <script src="processing-1.4.1.min.js"></script>
    <div id="canvasContainer">
    <canvas data-processing-sources="rectangles.pde"></canvas>
    </div>
</body>
like image 503
geotheory Avatar asked Dec 26 '12 16:12

geotheory


2 Answers

In 2018 I'd use

html, body { 
  margin: 0;
  height: 100%;
}
canvas {
  width: 100%;
  height: 100%;
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  z-index: -9999;
}

Here's why:

I used to recommend canvas { width: 100vw; height: 100vh; ...} but sadly mobile browsers broke vh so it's useless and will apparently be useless forever. See this blog post.

display: block; fixes some issues with scrollbars on certain browsers. Some pages use html, body { overflow: none; } but again that doesn't make sense if your page ends up needing to be taller than the screen/window.

position: fixed; makes the canvas position relative to the top of window so it won't scroll with the page. If you use position: absolute then the canvas will scroll off the top if the page is taller than the screen/window. For example this page.

top: 0; left 0; puts it at the top left. Without that it would default to it's default position which is inside the body's margins. Often this is solved by setting body { margin: 0; } but generally that means you end up needing some other container to add a margin back in otherwise your normal content gets positioned at the edge of the window.

z-index: -9999; is there to try to force it further back than anything else just in case the page itself is using some negative values for z-index

Here's an example as a snippet

var ctx = document.querySelector("canvas").getContext("2d");

function resize(canvas) {
  var width = canvas.clientWidth;
  var height = canvas.clientHeight;
  if (width != canvas.width || height != canvas.height) {
    canvas.width = width;
    canvas.height = height;
  }
}

function render(time) {
  time *= 0.001;
  resize(ctx.canvas);
  ctx.save();
  var w = ctx.canvas.width;
  var h = ctx.canvas.height;
  var hw = w / 2;
  var hh = h / 2;
  ctx.clearRect(0, 0, w, h);
  ctx.strokeStyle = "red";
  ctx.translate(hw, hh);
  ctx.rotate(time * 0.1);
  for (var ii = 0; ii < 100; ++ii) {
    ctx.rotate(Math.sin(time * 0.1) * 0.2);
    ctx.strokeRect(-hw, -hh, w, h);
    ctx.scale(0.9, 0.9);
  }
  ctx.restore();

  requestAnimationFrame(render);
}
requestAnimationFrame(render);
html, body {
  margin: 0;
  height: 100%;
}
canvas {
  width: 100%;
  height: 100%;
  display: absolute;
  position: fixed;
  top: 0;
  left: 0;
  z-index: -9999;
}
<canvas></canvas>
<pre>
  some content that is in front of the canvas
  
  Let's
  
  try
  
  to
  
  make
  
  sure
  
  it's 
  
  long 
  
  enough
  
  that 
  
  we 
  
  can
  
  scroll
  
  down
  
  the 
  
  page
  
  so 
  
  we 
  
  can 
  
  see 
  
  that 
  
  position: fixed;
  
  is
  
  a
  
  better
  
  choice
  
  than
  
  position: absolute;
</pre>

And here's an example outside SO so you can view it easier full size.

iframes work as well

Note that there's the issue that if your canvas animation is interactive the elements in front of the canvas will eat the mouse/touch events. There's no easy solution I know of for that. You can mark everything but that canvas/iframe as pointer-events: none and mark the canvas/iframe as pointer-events: auto but then you run into the issue that no text on your page can be selected and no links can be clicked. You could then say set <a> tags to have pointer-events: auto so links work but I'm sure there will be issues here and there depending on what info is on your page (trying to copy an email address, or a location address, etc...)

like image 91
gman Avatar answered Sep 21 '22 23:09

gman


canvas {
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
    z-index:-1;
}
like image 40
Muhammad Talha Akbar Avatar answered Sep 23 '22 23:09

Muhammad Talha Akbar