Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将图元大小减小一个因子,然后将其增大一个因子至原始大小_Javascript_Rounding - Fatal编程技术网

Javascript 将图元大小减小一个因子,然后将其增大一个因子至原始大小

Javascript 将图元大小减小一个因子,然后将其增大一个因子至原始大小,javascript,rounding,Javascript,Rounding,首先,我知道我的问题的根源是Javascript的舍入,我只是不知道如何在这个特定的实例中缓解它 我有一个元素,我想让用户通过点击“缩小”按钮来降低高度。高度的降低将与元素的当前高度成比例-例如,如果元素的高度为100px,则在缩放因子设置为0.3的情况下缩小一次将使其高度降低到70px。再次缩小会将其高度降低到49px,以此类推 页面上还有一个“放大”按钮。缩小后,用户应该能够使用“放大”按钮再次增加元素的高度。关键是,放大时元素高度的每个增量都应该与缩小时看到的增量相匹配。例如,如果缩小时图

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

我有一个元素,我想让用户通过点击“缩小”按钮来降低高度。高度的降低将与元素的当前高度成比例-例如,如果元素的高度为100px,则在缩放因子设置为0.3的情况下缩小一次将使其高度降低到70px。再次缩小会将其高度降低到49px,以此类推

页面上还有一个“放大”按钮。缩小后,用户应该能够使用“放大”按钮再次增加元素的高度。关键是,放大时元素高度的每个增量都应该与缩小时看到的增量相匹配。例如,如果缩小时图元的高度为:100、70、49、34.3、24.01,则再次放大时,图元的高度将为24.01、34.3、49、70、100

我已经创建了一个小提琴来演示这个功能。您会注意到,如果您运行它,并在一行中最初单击“缩小”按钮(标记为“-”)七次,然后在一行中单击“放大”按钮七次,而不是将元素的高度返回到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);
  });
});
我知道这是由于计算中的四舍五入累积造成的,用于缩小然后再缩小,但我不知道如何避免它。您可以看到,我已经注释掉了几行,它们试图每次将元素的高度四舍五入到小数点后2位,但它们没有帮助。如果它们没有注释,元素的高度最终为96px,这对我来说意味着,即使我在将值设置为元素高度之前舍入到2dp,它仍然会以某种方式知道完整的、未舍入的数字,并在计算下一个新高度时使用它

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


有没有一种方法可以在我放大和缩小时计算元素的高度(实际上,你也可以先放大再缩小,但这需要更多的代码,所以我简化了它),从而确保在每次“缩放增量”时元素的高度始终是相同的?

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


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

$el.height = base_height * pow(2.7182, zoomAmount)
确保从e^0=1开始使用
zoomAmount=0

由于整数不存在舍入错误,因此可以保证具有一致的缩放级别。此解决方案的另一个优点是内存占用较低,因为您只需为文档的每个元素保存一个基准高度。

在数组中存储各种缩放大小对我来说是个好主意。存储值是这种情况下唯一可靠的选项。如果保留原始大小值,单独保留修改器,并从执行两个操作计算结束值,则在增加和减少修改器时不会出现任何舍入问题。实际上,您是否注意到,如果使用此选项进行放大,放大时得到23.7999999997,缩小时得到24?@Snowmonkey,它采用对象的高度
var currentHeight=$el.height()
,不是计算值。是的,我明白了——例如,你不必将高度设置为24.3px。当你这样做,然后再读回时,它将是一个整数。这正是我一直在寻找的优雅解决方案。我已经为任何想看到它的人更新了我的小提琴(我希望我理解了你的解释——它是这样工作的!)。
$el.height = base_height * pow(2.7182, zoomAmount)