将元素大小减小一个因子,然后按相同因子增加到原始大小

Decrease element size by a factor then increase by same factor to original size

首先,我知道我的问题的根源在于 Javascript 中的四舍五入,我只是不知道如何在这个特定实例中缓解它。

我有一个元素,我想让用户通过单击 'zoom out' 按钮来降低高度。高度的减少将与元素的当前高度成比例 - 例如,如果元素的高度为 100px,将缩放因子设置为 0.3 缩小一次会将其高度降低到 70px。再次缩小会将其高度降低到 49px,依此类推。

页面上还有一个'zoom in'按钮。缩小后,用户应该可以使用 'zoom in' 按钮再次增加元素的高度。至关重要的是,元素高度在放大时的每次增量都应与缩小时看到的增量相匹配。例如,如果缩小时元素的高度为:100, 70, 49, 34.3, 24.01,则再次放大时,元素的高度将为 24.01, 34.3, 49, 70 100.

我创建了一个 fiddle 来演示此功能 here。您会注意到,如果您 运行 它并最初连续点击 'zoom out' 按钮(标记为“-”)七次,然后连续点击 'zoom in' 按钮七次,而不是将元素的高度返回到 100px,它最终为 95.7142...px,并且放大时的其他高度与缩小时的高度也不匹配。

$(function() {
  var zoomAmount = 0.3;
  var $el = $("#testDiv");

  $("#zoomIn").click(function() {
    var currentHeight = $el.height();
    var newHeight = currentHeight * (1 / (1 - zoomAmount));
    //newHeight = Math.round(newHeight * 10000 / 10000);
    $el.height(newHeight);
    $el.html(newHeight);
    if (newHeight >= 100) {
        $("#zoomIn").prop("disabled", true);
    }
  });

  $("#zoomOut").click(function() {
    $("#zoomIn").prop("disabled", false);
    var currentHeight = $el.height();
    var newHeight = currentHeight * (1 - zoomAmount);
    //newHeight = Math.round(newHeight * 10000 / 10000);
    $el.height(newHeight);
    $el.html(newHeight);
  });
});

我知道这是由于用于缩小然后返回的计算中舍入的累积造成的,但我不知道如何避免它。您可以看到我已经注释掉了几行,这些行每次都试图将元素的高度四舍五入到小数点后两位,但它们无济于事。在未注释的情况下,元素的高度最终为 96px,这对我来说表明即使在将值设置为元素高度之前我四舍五入到 2dp,它仍然以某种方式知道完整的、未四舍五入的数字并在计算时使用它下一个新的高度。

我能想到的唯一解决方案是在我放大和缩小时将元素的高度值存储在一个数组中,这样当我在相反的方向放大时,新的高度从数组中查找而不是比重新计算,但感觉不是很优雅。此外,在我的实际应用程序中,页面上一次有几十个元素,每个元素都有不同的高度,所以我必须在自己的数组中跟踪每个元素的高度,这看起来更不优雅。

有没有办法在我缩小和放大时计算元素的高度(实际上你也可以放大然后缩小,但这需要更多代码所以我简化了它)这将确保在每个 'zoom increment' 元素的高度总是一样的?

您可以存储以前的值并在放大时弹出 (fiddle)。

$(function() {
    var values = [];

    $("#zoomIn").click(function() {
        var newHeight = values.pop();
        // ...
    });

    $("#zoomOut").click(function() {
        var currentHeight = $el.height(); // this value gets stored
        values.push(currentHeight);
        // ...
    });
});

使用指数函数,并将 zoomAmount 保持为整数(更好的名称应该是 zoomLevel)。因此,无需修改会累积舍入误差的浮点数,您只需执行 zoomAmount++zoomAmount-- ,然后通过将 floating-point 数字提升到 zoomAmount(通常是数字,然后您可以根据需要使用一些常量调整图形)。 例如:

$el.height = base_height * pow(2.7182, zoomAmount)

确保从 zoomAmount = 0 开始,因为 e^0 = 1。 由于整数不存在舍入误差,因此可以保证缩放级别一致。此解决方案的另一个优点是它占用的内存很少,因为您只需为文档的每个元素保存一个基本高度。