Rya*_*yan 2 javascript jquery canvas double-buffering
我有一个全屏画布,上面画有3个图像.当我调整窗口大小时,这些图像会改变位置; 然而,它似乎非常小问题,在Firefox中更是如此.
我一直在读,双缓冲应该可以解决这个问题,但是我想知道当下一个位置未知时我将如何加倍缓冲.也就是说,我无法确定将来应该缓存什么,那么这怎么可能呢?
这是一个看似可行的来源,但我并不完全理解Fedor试图解释的概念.
到目前为止,我有,
$canvas = $('#myclouds')[0];
$canvas_buffer = $('canvas')[0].insertAfter($canvas).css('visibility', 'hidden');
context = $canvas.getContext('2d');
context_buffer = $canvas_buffer.getContext('2d');
clouds_arr = [$canvas, $canvas_buffer];
$(window).resize(function () {
drawCanvas();
};
function initCanvas() {
// Sources for cloud images
var cloud1 = '/js/application/home/images/cloud1.png',
cloud2 = '/js/application/home/images/cloud2.png',
cloud3 = '/js/application/home/images/cloud3.png';
// add clouds to be drawn
// parameters are as follows:
// image source, x, y, ratio, adjustment)
addCloud(cloud1, null, 125, .03);
addCloud(cloud2, null, 75, .15);
addCloud(cloud3, null, 50, .55);
addCloud(cloud1, null, 125, .97, 300);
addCloud(cloud2, null, 70, .85, 300);
addCloud(cloud3, null, 45, .5, 300);
// Draw the canvas
drawCanvas();
}
function drawCanvas() {
// Reset
$canvas.attr('height', $window.height()).attr('width', $window.width());
// draw the clouds
var l = clouds.length;
for (var i = 0; i < l; i++) {
clouds[i].x = ($window.width() * clouds[i].ratio) - clouds[i].offset;
drawimage(context, clouds[i]);
}
}
function Cloud() {
this.x = 0;
this.y = 0;
}
function addCloud(path, x, y, ratio, offset) {
var c = new Cloud;
c.x = x;
c.y = y;
c.path = path;
c.ratio = ratio || 0;
c.offset = offset || 0;
clouds.push(c);
}
function drawimage(ctx, image) {
var clouds_obj = new Image();
clouds_obj.src = image.path;
clouds_obj.onload = function() {
ctx.drawImage(clouds_obj, image.x, image.y);
};
}
Run Code Online (Sandbox Code Playgroud)
我想也许你误解了双缓冲是什么.它是一种在显示器上平滑实时渲染图形的技术.
这个概念是你有两个缓冲区.任何时候只能看到一个.当你去绘制构成一个框架的元素时,你将它们绘制到不可见的缓冲区.在你的情况下云.然后翻转缓冲区,使隐藏的缓冲区可见,隐藏可见的缓冲区.然后在下一帧上绘制到现在新隐藏的缓冲区.然后在绘图结束时你回头.
这样做是为了阻止用户在帧完成之前看到元素的部分渲染.在游戏系统上,这也将与显示器的垂直刷新同步,以实现非常平滑并且停止诸如撕裂之类的伪像.
看看上面的代码,你似乎已经创建了两个canvas元素,但是你只使用了第一个Context对象.我认为这是不完整的,因为没有发生翻转.
值得注意的是,窗口调整大小事件可以在拖动时连续触发,这可能导致疯狂渲染.我通常在resize事件上创建一个计时器来实际重新渲染.这样,只有在用户停止调整大小几毫秒后才会重新渲染.
此外,您的绘图例程每次都不需要创建新的Image对象.您可以使用一个图像对象并多次渲染到画布.这将大大加快渲染速度.
希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
2429 次 |
| 最近记录: |