HTML5 动态创建画布。

91

你好,我有一个关于使用JavaScript动态创建画布的问题。

我是这样创建画布的:

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";

但是当我尝试定位它时,得到了一个 null 值:

cursorLayer = document.getElementById("CursorLayer");

我做错了吗?有没有更好的方法使用JavaScript创建画布?


5个回答

144
问题在于您没有将画布元素插入文档正文中。
只需执行以下操作:
document.body.appendChild(canvas);

例子:

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);


11
或者只需使用document.body.appendChild(canvas)(无需使用getElementsByTagName搜索)- 它是文档对象的一个属性。 - Gerrat
@Gerrat 很好的发现。谢谢!不过,两种方式都是可行的。 - VisioN
如何将画布附加到特定的 div 上?$("div").appendChild(canvas) 可以实现吗? - kannan D.S
但是我该如何使其成为可能? - kannan D.S
澄清一下,你不仅要做以下操作,还需要创建它。最好的答案通常包含所有信息。但是没错。 - Octopus
显示剩余2条评论

2
这是因为您在DOM加载之前调用了它。首先创建元素并添加属性,然后在DOM加载后调用它。在您的情况下,应该像这样:
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");
}

1
这是错误的,创建新元素不会触发window.onload... - pasx
它并不会,但是在创建元素后不能够立即调用太快的元素。创建元素并立即调用将返回 null,但如果稍等一下或添加 window.onload,则会返回 HTMLElement。 - goblin01
好的,我更明白你的观点了。在页面加载的情况下这是有意义的,但我在已经加载的页面上进行了测试。 - pasx

1

替代方案

使用元素 .innerHTML=,这在现代浏览器中相当快速

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 }


1

13
这个简单的任务通常不需要使用 jQuery。 - boxtrain

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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接