[使用Fabric.js更改每次缩放的画布大小

问题描述 投票:0回答:1

我正在构建文档查看器,并且文档的每一页都变成图像,并且所有这些都在html画布上一个接一个地合并。

我正在使用FabricJS用图像填充画布。当我缩放画布内的图像时,它们可以完美地放大和缩小,但画布本身保持不变。

我希望更改画布大小,以便在需要时隐藏并显示滚动条。

这里是构建和填充画布的代码:

buildCanvas: function (images, length, maximumWidth, totalHeight) {
    var height = 10;

    var canvasContainer = document.getElementById("canvasContainer");
    var c = document.createElement("canvas");
    c.width = canvasContainer.offsetWidth - 20;
    c.height = totalHeight;
    engine.canvasObject = new fabric.Canvas(c);

    for (var index = 0; index < length; index++) {
        var imgInstance = new fabric.Image(images[index], {
            left: ((canvasContainer.offsetWidth / 2) - (maximumWidth / 2)),
            top: height
        });
        var ratio = 1;
        if (images[index].width > engine.maxWidth) {
            ratio = engine.maxWidth / images[index].width;
            imgInstance.scale(ratio);
            maximumWidth = engine.maxWidth;
        }
        engine.canvasObject.add(imgInstance);
        height += (images[index].height * ratio) + 15;
    }

    canvasContainer.appendChild(c);
},

这是我用来放大和缩小的代码:

zoom: function (ratio) {
    var canvasContainer = document.getElementById("canvasContainer");
    var middleX = canvasContainer.offsetWidth / 2;
    var middleY = 0;

    var zoom = engine.canvasObject.getZoom();
    engine.canvasObject.setHeight(engine.canvasObject.getHeight() * ratio);
    //engine.canvasObject.setWidth(engine.canvasObject.getWidth() * (zoom + (ratio - 1)));
    engine.canvasObject.zoomToPoint({ x: middleX, y: middleY }, zoom + (ratio - 1));
}

更改此行中所写画布的高度:

engine.canvasObject.setHeight(engine.canvasObject.getHeight() * ratio);

似乎可以完成工作,但是我找不到改变宽度的公式。无论我尝试了什么,当我单击几次后缩小时,由于画布宽度减小的变化太大,页面开始被“剪切”(主要在右侧)。

我想我正在寻找的是一种了解画布内实际绘制图像的高度和宽度的方法。

我尝试使用getImageData方法和toDataUrl方法获取它,但它们对我没有好处。

感谢您的帮助

javascript html canvas html5-canvas fabricjs
1个回答
0
投票

功能engine.canvasObject.zoomToPoint执行均匀缩放

    在调用width之后,必须缩放画布heightzoomToPoint以适合其内容。
  • 当调用功能缩放时,画布是当前缩放的正确尺寸。getHeight返回画布宽度和高度时没有舍入,并由setHeight设置]
  • 然后画布分辨率可以按(zoom + (ratio - 1)) / zoom缩放...
  • const currentZoom = engine.canvasObject.getZoom(); const newZoom = currentZoom + (ratio - 1); const height = engine.canvasObject.getHeight(); const width = engine.canvasObject.getWidth(); const zoomBy = newZoom / currentZoom; // the amount to scale canvas engine.canvasObject.setHeight(height * zoomBy); engine.canvasObject.setWidth(width * zoomBy); engine.canvasObject.zoomToPoint({ x: middleX, y: middleY }, newZoom);

    这将放大或缩小。

    如果将(zoom + (ratio - 1))缩放为零,则缩放量zoom === -(ratio - 1)可能会失败。

    注意

    如果当前变焦非常小而新变焦很大,则画布尺寸可能会变得太大。为了安全起见,您应该审核新的zoom值,以防止过大的画布可能会使页面崩溃或使其变慢。

    环境问题

    如果画布大小四舍五入为整数,则该错误将随着时间的流逝而增大。仅当您多次缩放画布时,这才是问题。

    为了避免此错误,您需要具有参考比例。画布在特定比例尺上的大小。

    例如

    const canvasScaleReference = { zoom: 2, // At this zoom the canvas width: 500, // is 500 height: 1000, // by 1000 };

    这意味着在缩放1时,画布是250 x 500

    因此,缩放和缩放画布的功能是>

    const zoom = engine.canvasObject.getZoom() + (ratio - 1); const height = canvasScaleReference.height / canvasScaleReference.zoom * zoom; const width = canvasScaleReference.width / canvasScaleReference.zoom * zoom; engine.canvasObject.setHeight(height); engine.canvasObject.setWidth(width); engine.canvasObject.zoomToPoint({ x: middleX, y: middleY }, zoom);

    因为这使用固定参考,所以舍入误差不会累积。

  • © www.soinside.com 2019 - 2024. All rights reserved.