我可以将画布图像居中吗

Lou*_*uis 0 javascript canvas html5-canvas

我正在绘制一个大的画布图像作为背景,该图像大于窗口大小。我想知道是否有办法将图像居中放置在全屏上。如果是这样,怎么办?这就是我在做什么:

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

        window.addEventListener('resize', resizeCanvas, false);

        function resizeCanvas() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;

            drawStuff(); 
        }

        resizeCanvas();

        function drawStuff() {
            var imageObj = new Image();

            imageObj.onload = function() {
                context.drawImage(imageObj, 69, 50);
            };

            imageObj.src = '/resources/img/bg.png';
        }        
Run Code Online (Sandbox Code Playgroud)

小智 5

这是不使用transform将图像居中放置在画布上的一种可选方式(另请参见下面的注释):

imageObj.onload = function() {

    var x = (canvas.width  - this.width ) * 0.5,   // this = image loaded
        y = (canvas.height - this.height) * 0.5;

    ctx.drawImage(this, x, y);
};
Run Code Online (Sandbox Code Playgroud)

由于图像大于画布,因此x和y在这种情况下将为负数,这非常好。如果图像较小,则效果也一样好。如果在载荷处理程序之外进行绘制,则当然需要使用imageObj代替this。

注意:设置大小调整处理程序的方法不是处理图像重新定位的最佳方法-您只应加载一次图像,然后重用该对象。由于调整大小通常会产生许多事件,因此它将触发相等数量的图像重新加载。

为了使其正常工作,您可以改为执行以下操作:

var canvas = document.getElementById('canvas'),
    context = canvas.getContext('2d'),

    imageObj = new Image();  // declare globally

imageObj.onload = function() {

    // now set up handler when image is actually loaded
    // - else drawImage will fail (width, height is not available and no data)
    window.addEventListener('resize', resizeCanvas, false);

    // initial call to draw image first time
    resizeCanvas();  
};

imageObj.src = '/resources/img/bg.png';

function resizeCanvas() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    drawStuff(); 
}

function drawStuff() {
    var x = (canvas.width  - imageObj.width ) * 0.5,
        y = (canvas.height - imageObj.height) * 0.5;

    ctx.drawImage(imageObj, x, y);
}        
Run Code Online (Sandbox Code Playgroud)

由于resize事件队列仍然很大并且可能会滞后,因此它不是完美的-对此也有解决方案,例如,这个(稍作修改)。