Estoy revisando un angularJScódigo antiguo escrito por desarrolladores anteriores, y encontré uno if statementque verifica si la imagen tiene un tamaño de 1: 1 o 16/4 o 4/3 y, en caso afirmativo, se puede cargar la imagen.

Sin embargo, cuando trato de cargar una imagen en 16/4 o 4/3, simplemente se niega a cargar, como si no estuviera en el si. Solo funciona la relación 1:1.

Mi pregunta es ¿cómo podría reescribir el código para que funcione?

  $scope.$watch('file', function (val) {
        if (val != undefined) {
            if (!val[0].isImage) {
                $scope.errorMsg = 'It must be an image';
                $scope.disabled = true;
            }

            // This is the if that doesn't work well
                let ratio = Math.ceil(val[0].width / val[0].height);
                if (ratio == 16 / 9 || ratio == 4 / 3 || ratio == 1) {
                    $scope.errorMsg = '';
                    $scope.disabled = false;
                    $scope.saveFile();
                } else {
                    $scope.errorMsg = 'Your selected image must have the given ratio. (16:9 or 4:3 or 1:1)';
                    $scope.disabled = true;
                }
            }
        });

ingrese la descripción de la imagen aquí

Si usted tiene alguna pregunta no dude en preguntar.

respuesta

Al dividir números, JS (o casi cualquier otro idioma) tiene una precisión que usa. Esto significa que los resultados pueden diferir un poco de los resultados matemáticos.

Debe usar un rango al hacer comparaciones como esta. Entonces, en lugar de esperar que sea exactamente 16/9, debe esperar tener un error.

También debe eliminar el Math.ceilde su cálculo de proporción.

Puedes usar épsilon para esto. Algo como esto tal vez:

if (Math.abs(ratio - 16 / 9) < Number.EPSILON || Math.abs(ratio - 4 / 3) < number.EPSILON || ratio == 1)

Otro enfoque sería simplemente eliminar la división y usar solo multiplicaciones. Algo como esto

 if (val[0].width * 9 === val[0].height * 16)

Esto no tendrá un problema de precisión.