• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}