Javascript 如何将内容从隐藏画布复制到可见画布?
我在将画布从缓冲区画布复制到页面上的画布时遇到一些困难。到目前为止,我已经构建了一个渲染对象,一个关卡对象,并且我有我的主游戏循环(目前只是一个启动函数) 我能够在渲染对象中写入缓冲区画布(如果我添加了document.body.append()语句,画布会成功地将必要的内容附加到文档),但我无法从缓冲区画布复制到主画布。请参阅下面的代码片段:Javascript 如何将内容从隐藏画布复制到可见画布?,javascript,html,canvas,Javascript,Html,Canvas,我在将画布从缓冲区画布复制到页面上的画布时遇到一些困难。到目前为止,我已经构建了一个渲染对象,一个关卡对象,并且我有我的主游戏循环(目前只是一个启动函数) 我能够在渲染对象中写入缓冲区画布(如果我添加了document.body.append()语句,画布会成功地将必要的内容附加到文档),但我无法从缓冲区画布复制到主画布。请参阅下面的代码片段: function Renderer(bufferWidth, bufferHeight) { var c=document.createElem
function Renderer(bufferWidth, bufferHeight) {
var c=document.createElement('canvas');
var ctx=c.getContext('2d');
c.width=bufferWidth;
c.height=bufferHeight;
this.getBufferContext = function() { return ctx; };
this.getBufferElement = function() { return c; };
this.drawToCanvas = function(canvasCtx) {
canvasCtx.drawImage(c,0,0);
};
}
var c = document.getElementById('mycanvas');
var ctx = c.getContext('2d');
var render = new Renderer(c.width, c.height);
var level1 = new Level('images/imagequality.png');
level1.Draw(render.getBufferContext());
render.drawToCanvas(ctx);
请注意,渲染器位于单独的文件中,并使用“我的HTML”页面中的脚本标记加载
如前所述,drawToCanvas()函数似乎无法成功地将数据从一个画布复制到另一个画布。附加“我的源画布”可确认它包含预期的数据
编辑:我在下面列出了我的级别代码
function Level(mapname) {
var map=new Image();
map.src=mapname;
this.Draw = function(renderer) {
map.onload = function() { renderer.drawImage(map,0,0); };
};
}
我有好消息,也有坏消息 好消息是你在这里展示的代码100%有效 以下是演示: 坏消息:这意味着您的级别代码中的某些内容被破坏,因为我的存根级别代码在您的框架中可以完美地工作…:-( 存根级别:
function Level() {
this.Draw = function(xxctx) {
for (var i = 0; i < 30; i++) {
xxctx.moveTo(10 + (i * 40 % 300), 10 + (parseInt(i / 6, 10) * 40));
xxctx.lineTo(40 + (i * 40 % 300), 40 + (parseInt(i / 6, 10) * 40));
xxctx.moveTo(40 + (i * 40 % 300), 10 + (parseInt(i / 6, 10) * 40));
xxctx.lineTo(10 + (i * 40 % 300), 40 + (parseInt(i / 6, 10) * 40));
}
xxctx.stroke();
};
}
如果运行该代码,您将看到在调用onload
时,其他所有操作都已执行,您将注意到控制台将如何读取:
at 1
at 2
at 3
因此,在执行警报('drawing now!');
时
// render.drawToCanvas(ctx);
ctx.drawImage(Renderer_c, 0, 0);
将已经运行…基本上您的Draw()
函数实际上是一个异步“加载”。不幸的是,您当前的概念化不起作用。您的Draw()
函数需要是一个异步函数,如下所示:
function Level(mapname) {
var map=new Image();
document.body.appendChild(map); //add to show
map.src=mapname;
this.asyncDraw = function(renderer, onComplete) {
map.onload = function() {
renderer.drawImage(map,0,0);
onComplete();
};
};
}
然后,在您的示例中,应该像这样调用函数:
level1.asyncDraw(render.getBufferContext(), function() {
render.drawToCanvas(ctx);
});
我可能应该继续说,这种类型的异步性使得HTML5游戏编程有点棘手,因为你真的必须扔掉“加载…”微调器,在所有“资源”加载之前不要进入渲染循环。在所有实践中,你都需要“就绪”的概念,例如Load(fOnReady)
和Draw(ctx)
而不仅仅是asyncDraw(ctx,fOnReady)
更新后的jsbin如下:
希望这有帮助-ck感谢您的反馈。如果您感兴趣,我已将我的级别代码附加到原始文件中。那里没有发生什么特别的事情…到目前为止,它只是在提供的画布上下文(渲染器)中绘制单个图像。FWIW我有绘图代码(创建上下文、渲染器、级别等)在名为launch()的函数中,我在HTML页面的body.onload函数中调用了该函数。
level1.asyncDraw(render.getBufferContext(), function() {
render.drawToCanvas(ctx);
});