缩放后保持图像居中

时间:2015-10-23 21:45:22

标签: canvas html5-canvas

我在画布上绘制了一个图像,我希望能够以任何比例放大和缩小,同时保持图像在中心。为此,我的方法是更改​​画布上下文的比例并重新绘制图像,但我需要计算新图像的左上角,否则它不会居中。

function zoom( canvas, context, scale ) {
    var image = new Image();
    image.src = canvas.toDataURL( 'image/png' );
    canvas.clearRect( 0, 0, canvas.width, canvas.height );
    context.scale( scale, scale );
    var x = ???,
        y = ???;
    context.drawImage( image, x, y );
}

问题是如何以适合任何比例的方式计算xy。我已经找到了一些特殊情况,但我无法找到一般规则。当比例为0.5时,保持图像居中的规则是:

var x = canvas.width / 2,
    y = canvas.height / 2;

当比例为2时,规则为:

var x = -canvas.width / 4,
    y = -canvas.height / 4;

当比例为3时,规则为:

var x = -canvas.width / 3,
    y = -canvas.height / 3;

那么一般规则是什么?或者有更好的方法吗?

2 个答案:

答案 0 :(得分:5)

对于中心。

最好这样做。 ctx是画布上下文

// scale the coordinate system to required scale and set the origin (0,0) 
// to the center of the canvas
ctx.setTransform(scale, 0, 0, scale, ctx.canvas.width / 2, ctx.canvas.height / 2);
ctx.drawImage(image,-image.width / 2,-image.height / 2); // draw the image offset by half

或者您可以避免设置转换并只绘制缩放的图像

// get the position is half of the canvas width minus the scaled width of the image 
var x = (ctx.canvas.width - image.width * scale) / 2;
var y = (ctx.canvas.height - image.height * scale) / 2;
ctx.drawImage(image, x, y, image.width * scale, image.height * scale); // drw image with scaled width and height 

或者根据需要缩放画布并将原点保留在左上角。因为画布不会改变它的实际大小,你必须反转比例变化,这意味着将它的大小除以比例而不是乘以。

ctx.scale(scale, scale);
var x = (ctx.canvas.width / scale - image.width) / 2;
var y = (ctx.canvas.height / scale - image.height) / 2;
ctx.drawImage(image, x, y);

答案 1 :(得分:0)

  getWidth() {
        return this.rect.width * this.scale;
    }

    getHeight() {
        return this.rect.height * this.scale;
    }

    setScale(scale) {

        const oldWidth = this.getWidth();
        const oldHeight = this.getHeight();
        this.scale = scale;
        const newWidth = this.getWidth();
        const newHeight = this.getHeight();

        const addedWidth = newWidth - oldWidth;
        const addedHeight = newHeight - oldHeight;

        this.rect.pos.x -= addedWidth / 2;
        this.rect.pos.y -= addedHeight / 2;
    }