4

为什么这不起作用?

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


var img = new Image();
img.onload = function(){
    ctx.drawImage(img,0,0);
};
img.src = 'hero.png';

但这可以吗?

var img = new Image();
img.onload = function(){
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    ctx.drawImage(img,0,0);
};
img.src = 'hero.png';

如何使该ctx 变量成为全局变量,以便我可以在所有函数中使用?顺便说一句,在所有教程中,每个人都使用第一种方法......

得到它的工作!

4

3 回答 3

5

我怀疑原因是时间安排:如果您的代码位于定义script元素的上方的元素中,id "canvas"则您的第一个代码块将不会在document.getElementById("canvas")调用中找到它,因为它还不存在。通过等待图像加载,您稍后会检查它,当它存在时。

如果我是正确的,解决方案是将块移动到元素script的末尾,就在结束标签之前(或者标签之后的任何地方,真的)。body</body>canvas

例如,而不是:

<!-- ... -->
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');


var img = new Image();
img.onload = function(){
    ctx.drawImage(img,0,0);
};
img.src = 'hero.png';
</script>
<!-- ... -->
<canvas id="canvas"></canvas>
<!-- ... -->
</body>

做这个:

<!-- ... -->
<canvas id="canvas"></canvas>
<!-- ... -->
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');


var img = new Image();
img.onload = function(){
    ctx.drawImage(img,0,0);
};
img.src = 'hero.png';
</script>
</body>

无论如何,把你的脚本放在文件的底部是个好主意,更多:YUI Best Practices for Speeding Your Website

于 2013-05-05T11:06:55.747 回答
1

因为尚未加载 html 并且 #canvas 元素不存在。

你可以试试这个:

var canvas, ctx;
var img = new Image();
img.onload = function(){
    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');
    ctx.drawImage(img,0,0);
};
img.src = 'hero.png';
于 2013-05-05T11:08:26.387 回答
0

我最好的猜测是“线程”(或事件)。

当您调用 时getContext,它会初始化一个新的图形上下文,并且在您的浏览器尝试重绘屏幕之前它需要它的结果。通常,第一种方法应该不是什么大问题,只要它同步运行(阻塞,换句话说:它立即返回)。但是一旦你的浏览器需要异步做一些事情,它就“厌倦了等待”你的上下文,它开始重绘你的屏幕而不等待结果,因此你的上下文无效。然后,您需要初始化一个新的上下文以便将内容绘制到您的画布上。

这显然取决于浏览器的实现,而我的猜测仅基于其他地方的图形环境(例如 CoreGraphics、OpenGL 等)中发生的情况。图形在单个线程上运行,并且该线程不会简单地等待赶上您的其他线程。尽管 Javascript 抽象了很多,但在构建图形应用程序时需要牢记这一点。

于 2013-05-05T11:07:37.303 回答