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

时间:2017-01-23 15:47:38

标签: javascript rounding

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

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

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

我已经创建了一个演示此功能的小提琴here。您会注意到,如果您运行它并且最初点击“缩小”&#39;按钮(标有&#39; - &#39;)连续七次,然后点击&#39;放大&#39;按钮连续七次,而不是将元素的高度返回到100px,最终为95.7142 ... px,放大的其他高度与缩小时的高度相匹配。< / p>

$(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);
  });
});

据我所知,这是由用于缩小然后重新进入的计算中的舍入累积引起的,但我不知道如何避免它。你可以看到,我已经注释了几行试图将元素的高度每次都缩小到2位小数,但是他们没有帮助。在没有注释的情况下,元素的高度最终为96px,这告诉我即使我在将值设置为元素的高度之前舍入到2dp,它仍然是在某种程度上意识到完整的,未接地的数字,并在计算下一个新的高度时使用它。

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

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

2 个答案:

答案 0 :(得分:2)

使用指数函数,并将zoomAmount保持为整数(更好的名称将类似于zoomLevel)。因此,您可以简单地执行zoomAmount++zoomAmount--,而不是修改会累积舍入误差的浮点数,然后通过将浮点数提升为{{1}来获取元素的实际比例(通常是数字,然后您可以根据需要调整一些常量的图形)。 例如:

zoomAmount

请确保以$el.height = base_height * pow(2.7182, zoomAmount) 开头,因为e ^ 0 = 1。 由于整数不存在舍入误差,因此可确保您具有一致的缩放级别。此解决方案的另一个优点是内存占用少,因为您只需为文档的每个元素保存一个基本高度。

答案 1 :(得分:0)

您可以存储以前的值,然后弹回放大(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);
        // ...
    });
});