1/* 2 * Copyright (c) 2022-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { asFloat64, asString, float64 } from "@koalaui/compat" 17 18/** 19 * Computes the linear interpolation between `source` and `target` based on `weight`. 20 * 21 * @param weight - interpolation factor in the range [0..1] 22 * @param source - a value corresponding to weight 0 23 * @param target - a value corresponding to weight 1 24 * @returns interpolated value 25 */ 26export function lerp(weight: float64, source: float64, target: float64): float64 { 27 return source * (1.0 - weight) + target * weight 28} 29 30/** 31 * Clamps a {@link value} within the specified range. 32 * 33 * @param value - a value to clamp 34 * @param min - the lower boundary of the range 35 * @param max - the upper boundary of the range 36 * @returns `min` if `value` is less than `min`, 37 * `max` if `value` is greater than `max`, 38 * `value` otherwise 39 */ 40export function clamp(value: float64, min: float64, max: float64): float64 { 41 return value <= min ? min : value >= max ? max : value 42} 43 44/** 45 * Calculates the difference between the argument and 46 * the largest (closest to positive infinity) integer value 47 * that is less than or equal to the argument. 48 * 49 * @param value a floating-point value to process 50 * @returns a floor modulus of the given value in the range [0..1) 51 */ 52export function modulo(value: float64): float64 { 53 // The casts below are needed since floor returns double in ArkTS 54 const modulo: float64 = value - Math.floor(value) 55 return (modulo < 1.0) ? modulo : 0.0 56} 57 58/** 59 * @param str a string to parse 60 * @param name a name for error message 61 * @param verify whether to verify parsing validity 62 * @returns a floating-point number 63 * @throws Error if `str` cannot be parsed 64 */ 65export function parseNumber(str: string, name: string = "number", verify: boolean = false): float64 { 66 if (str != "") { // do not parse empty string to 0 67 // ArkTS does not support NaN, isNaN, parseFloat 68 const value = asFloat64(str) 69 if (verify) { 70 const reverseStr = asString(value) 71 if (reverseStr !== undefined && reverseStr?.length == str.length && reverseStr == str) { 72 return value 73 } 74 } 75 else { 76 return value 77 } 78 } 79 throw new Error(`cannot parse ${name}: "${str}"`) 80} 81 82/** 83 * An ArkTS-compliant replacement for {@link isFinite}. 84 */ 85export function isFiniteNumber(number: float64): boolean { 86 // With Node.js: 87 // isFiniteNumber(Number.NEGATIVE_INFINITY) == false 88 // isFiniteNumber(Number.POSITIVE_INFINITY) == false 89 // isFiniteNumber(NaN) == false 90 return number >= Number.MIN_SAFE_INTEGER && number <= Number.MAX_SAFE_INTEGER 91} 92 93export function getDistancePx(startX: float64, startY: float64, endX: float64, endY: float64): float64 { 94 const cathetA = Math.abs(endX - startX) 95 const cathetB = Math.abs(endY - startY) 96 return Math.sqrt(cathetA * cathetA + cathetB * cathetB) as float64 97}