90

Hi there I have a question about dynamically creating a canvas using javascript.

I create a canvas like this:

var canvas = document.createElement('canvas');
canvas.id     = "CursorLayer";
canvas.width  = 1224;
canvas.height = 768;
canvas.style.zIndex   = 8;
canvas.style.position = "absolute";
canvas.style.border   = "1px solid";

but when I try to locate it, I get a null value:

cursorLayer = document.getElementById("CursorLayer");

Am I doing it wrong? Is there a better way to create a canvas using JavaScript?

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
Arjen van Heck
  • 1,086
  • 1
  • 7
  • 9
  • 2
    Possible duplicate of [Add canvas to a page with javascript](http://stackoverflow.com/questions/9152224/add-canvas-to-a-page-with-javascript) – Vadzim Jun 04 '16 at 13:01

5 Answers5

143

The problem is that you do not insert your canvas element in the document body.

Just do the following:

document.body.appendChild(canvas);

Example:

var canvas = document.createElement('canvas');

canvas.id = "CursorLayer";
canvas.width = 1224;
canvas.height = 768;
canvas.style.zIndex = 8;
canvas.style.position = "absolute";
canvas.style.border = "1px solid";


var body = document.getElementsByTagName("body")[0];
body.appendChild(canvas);

cursorLayer = document.getElementById("CursorLayer");

console.log(cursorLayer);

// below is optional

var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgba(255, 0, 0, 0.2)";
ctx.fillRect(100, 100, 200, 200);
ctx.fillStyle = "rgba(0, 255, 0, 0.2)";
ctx.fillRect(150, 150, 200, 200);
ctx.fillStyle = "rgba(0, 0, 255, 0.2)";
ctx.fillRect(200, 50, 200, 200);
Neil
  • 1,275
  • 11
  • 25
VisioN
  • 143,310
  • 32
  • 282
  • 281
2

It happens because you call it before DOM has loaded. Firstly, create the element and add atrributes to it, then after DOM has loaded call it. In your case it should look like that:

var canvas = document.createElement('canvas');
canvas.id     = "CursorLayer";
canvas.width  = 1224;
canvas.height = 768;
canvas.style.zIndex   = 8;
canvas.style.position = "absolute";
canvas.style.border   = "1px solid";
window.onload = function() {
    document.getElementById("CursorLayer");
}
goblin01
  • 91
  • 4
  • 1
    This is wrong, creating a new element does not trigger window.onload... – pasx Mar 08 '18 at 19:30
  • It does not, but you can't call too fast elements after created. Creating element and calling it will return null, but if you wait a bit or add window.onload it will return HTMLElement. – goblin01 Mar 09 '18 at 19:28
  • OK I understand better what your point is. It makes sense in the context of a page being loaded but I tested it in the context of an already loaded page. – pasx Mar 11 '18 at 22:09
1

Via Jquery:

$('<canvas/>', { id: 'mycanvas', height: 500, width: 200});

http://jsfiddle.net/8DEsJ/736/

Michael Yagudaev
  • 6,049
  • 3
  • 48
  • 53
Razan Paul
  • 13,618
  • 3
  • 69
  • 61
1

Alternative

Use element .innerHTML= which is quite fast in modern browsers

document.body.innerHTML = "<canvas width=500 height=150 id='CursorLayer'>";


// TEST

var ctx = CursorLayer.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(100, 100, 50, 50);
canvas { border: 1px solid black }
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
1
 <html>
 <head></head>
 <body>
 <canvas id="canvas" width="300" height="300"></canvas>
 <script>
  var sun = new Image();
  var moon = new Image();
  var earth = new Image();
  function init() {
  sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
  moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
  earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
  window.requestAnimationFrame(draw);
  }

  function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  ctx.globalCompositeOperation = 'destination-over';
  ctx.clearRect(0, 0, 300, 300);

  ctx.fillStyle = 'rgba(0, 0, 0, 0.4)';
  ctx.strokeStyle = 'rgba(0, 153, 255, 0.4)';
  ctx.save();
  ctx.translate(150, 150);

  // Earth
  var time = new Date();
  ctx.rotate(((2 * Math.PI) / 60) * time.getSeconds() + ((2 * Math.PI) / 60000) * 
  time.getMilliseconds());
  ctx.translate(105, 0);
  ctx.fillRect(10, -19, 55, 31); 
  ctx.drawImage(earth, -12, -12);

   // Moon
  ctx.save();
  ctx.rotate(((2 * Math.PI) / 6) * time.getSeconds() + ((2 * Math.PI) / 6000) * 
  time.getMilliseconds());
  ctx.translate(0, 28.5);
  ctx.drawImage(moon, -3.5, -3.5);
  ctx.restore();

  ctx.restore();

   ctx.beginPath();
   ctx.arc(150, 150, 105, 0, Math.PI * 2, false);
   ctx.stroke();

   ctx.drawImage(sun, 0, 0, 300, 300);

   window.requestAnimationFrame(draw);
    }

   init();
   </script>
   </body>
   </html>
Pooja
  • 21
  • 3