ducjs
Version:
The duc 2D CAD file format is a cornerstone of our advanced design system, conceived to cater to professionals seeking precision and efficiency in their design work.
262 lines (261 loc) • 15.4 kB
TypeScript
import { UNIT_SYSTEM } from "../flatbuffers/duc";
import { PrecisionValue, RawValue, ScaledZoom, Scope, ScopedValue, ScopedZoomValue, ValueOf } from "../types";
import { DucPoint } from "../types/elements";
import { GeometricPoint } from "../types/geometryTypes";
export type UnitSystem = ValueOf<typeof UNIT_SYSTEM>;
export type ZoomDirection = 'up' | 'down' | 'neutral';
export declare const MIN_ZOOM = 1e-32;
export declare const MAX_ZOOM = 1e+32;
export declare const NEUTRAL_SCOPE: SupportedMeasures;
export declare const metricMeasures: readonly ["qm", "rm", "ym", "zm", "am", "fm", "pm", "Å", "nm", "µm", "mm", "cm", "dm", "m", "dam", "hm", "km", "Mm", "Gm", "Tm", "Pm", "Em", "Zm", "Ym", "Rm", "Qm"];
export type MetricMeasure = typeof metricMeasures[number];
export declare const imperialMeasures: readonly ["th", "ln", "in", "h", "ft", "yd", "rd", "ch", "fur", "mi", "lea"];
export type ImperialMeasure = typeof imperialMeasures[number];
export type SupportedMeasures = MetricMeasure | ImperialMeasure;
export type CombinedMeasure = SupportedMeasures;
export interface UnitDefinition {
prefix: SupportedMeasures;
unit: string;
full: string;
exponent: number;
}
export declare const metricUnits: UnitDefinition[];
export declare const imperialUnits: UnitDefinition[];
export declare const ScaleFactors: {
[key in CombinedMeasure]: number;
};
/**
* Determines if a measure belongs to the metric system.
* @param measure The measure to check.
* @returns `true` if the measure is metric, `false` otherwise.
*/
export declare function isMetricMeasure(measure: SupportedMeasures): boolean;
/**
* Gets the unit system ('metric' or 'imperial') for a given measure.
* @param measure The measure to determine the system for.
* @returns The unit system the measure belongs to.
*/
export declare function getUnitSystemForMeasure(measure: SupportedMeasures): UnitSystem;
/**
* Clamps a zoom value between minimum and maximum allowed values
*/
export declare function clampZoom(zoom: number): number;
/**
* Determines the zoom direction based on previous and current zoom values
*/
export declare function getZoomDirectionChange(prevZoom: number, currentZoom: number): ZoomDirection;
/**
* Gets the unit definitions (prefix, name, exponent) for the specified unit system.
* @param unitSystem The unit system ('metric' or 'imperial') to get definitions for.
* @returns An array of unit definitions.
*/
export declare function getUnitDefinitions(unitSystem: UnitSystem): UnitDefinition[];
/**
* Gets the standard exponents associated with the units in a specified system.
* These exponents represent the power of 10 (for metric) or log10 equivalent (for imperial) relative to the base unit (meter).
* @param unitSystem The unit system ('metric' or 'imperial').
* @returns An array of standard exponent numbers.
*/
export declare function getStandardExponents(unitSystem: UnitSystem): number[];
/**
* Gets the exponent value for a given measure.
* @param measure The measure (e.g., 'mm', 'ft') to get the exponent for.
* @returns The exponent value, defaulting to 0 (base unit) if not found.
*/
export declare function getExponentForMeasure(measure: SupportedMeasures): number;
/**
* Gets the measure (unit prefix) that is closest to a given exponent value within a unit system.
* @param exponent The exponent value to find the closest measure for.
* @param unitSystem The unit system ('metric' or 'imperial') to search within.
* @returns The prefix of the closest measure.
*/
export declare function getMeasureForExponent(exponent: number, unitSystem: UnitSystem): SupportedMeasures;
/**
* Calculates how much influence the main scope should have based on zoom level.
* This function now provides a simple normalized distance metric for UI animations.
*
* Returns a value from 0 to 1 where:
* - 1 means we're exactly at the main scope's exponent
* - 0 means we're at or beyond the threshold from the main scope's exponent
*/
export declare function getMainScopeInfluence(zoomExponent: number, mainScopeExponent: number, scopeExpThreshold: number): number;
/**
* Calculates the appropriate scope index based on zoom level with an improved gravity well effect
*/
export declare function calculateScopeIndex(zoom: number, unitSystem: UnitSystem, scopeExpThreshold: number, mainScopeExponent: number): number;
/**
* Calculates the appropriate scope measure (unit prefix) based on the current zoom level,
* considering the main scope and threshold settings.
* @param zoom The current raw zoom level.
* @param scopeExpThreshold The exponent difference threshold for main scope influence.
* @param mainMeasure The designated main measure acting as a gravity well.
* @returns The calculated scope measure (unit prefix).
*/
export declare function calculateScope(zoom: number, scopeExpThreshold: number, mainMeasure: SupportedMeasures): SupportedMeasures;
/**
* Gets the full unit definition object for the current scope based on zoom and main scope settings.
* @param zoom The current raw zoom level.
* @param scopeExpThreshold The exponent difference threshold for main scope influence.
* @param mainMeasure The designated main measure.
* @returns The full UnitDefinition object for the current scope.
*/
export declare function getCurrentUnitDefinition(zoom: number, scopeExpThreshold: number, mainMeasure: SupportedMeasures): UnitDefinition;
/**
* Gets the lower bound of the current scope's *exponent* range.
* This represents the minimum exponent value covered by the current scope.
* @param zoom The current raw zoom level.
* @param scopeExpThreshold The exponent difference threshold for main scope influence.
* @param mainMeasure The designated main measure.
* @returns The lower exponent bound of the current scope.
*/
export declare function getCurrentScopeExponentLowerBound(zoom: number, scopeExpThreshold: number, mainMeasure: SupportedMeasures): number;
/**
* Gets the upper bound of the current scope's *exponent* range.
* This represents the maximum exponent value covered by the current scope (exclusive).
* @param zoom The current raw zoom level.
* @param scopeExpThreshold The exponent difference threshold for main scope influence.
* @param mainMeasure The designated main measure.
* @returns The upper exponent bound of the current scope.
*/
export declare function getCurrentScopeExponentUpperBound(zoom: number, scopeExpThreshold: number, mainMeasure: SupportedMeasures): number;
/**
* Gets the lower bound of the *zoom* range for the current scope.
* Derived from the scope's upper exponent bound.
* @param zoom The current raw zoom level.
* @param scopeExpThreshold The exponent difference threshold for main scope influence.
* @param mainMeasure The designated main measure.
* @returns The minimum raw zoom value that falls within the current scope.
*/
export declare function getCurrentScopeLowerZoomBound(zoom: number, scopeExpThreshold: number, mainMeasure: SupportedMeasures): number;
/**
* Gets the upper bound of the *zoom* range for the current scope.
* Derived from the scope's lower exponent bound.
* @param zoom The current raw zoom level.
* @param scopeExpThreshold The exponent difference threshold for main scope influence.
* @param mainMeasure The designated main measure.
* @returns The maximum raw zoom value (exclusive) that falls within the current scope.
*/
export declare function getCurrentScopeUpperZoomBound(zoom: number, scopeExpThreshold: number, mainMeasure: SupportedMeasures): number;
/**
* Converts a numeric value from one scope (unit) to its equivalent in another scope,
* preserving the actual physical magnitude.
* This uses the underlying scale factors relative to the base unit (meter).
*
* @param providedValue - The numeric value to convert.
* @param providedScope - The scope (unit) of the provided value.
* @param targetScope - The target scope (unit) to convert the value to.
* @returns The equivalent value in the target scope.
*/
export declare function getPrecisionValueForScope(providedValue: number, providedScope: SupportedMeasures, targetScope: SupportedMeasures): number;
/**
* Gets the percentage through the current scope's *exponent* range (0-100%)
* Percentage 0% means at the boundary with the next *larger* unit scope
* Percentage 100% means at the boundary with the next *smaller* unit scope
*/
export declare function getScopeThroughPercentage(zoom: number, scopeExpThreshold: number, mainMeasure: SupportedMeasures): number;
/**
* Gets proximity to scope change (0-1, where 1 means about to change)
* This determines animation of measurement indicators
*/
export declare function getProximityToScopeChange(zoom: number, scopeExpThreshold: number, mainMeasure: SupportedMeasures): number;
/**
* Determines direction of next scope change based on position within current scope
* 'up' -> higher index (larger units)
* 'down' -> lower index (smaller units)
*/
export declare function getNextScopeDirection(zoom: number, scopeExpThreshold: number, mainMeasure: SupportedMeasures): 'up' | 'down';
/**
* Get translation factor between two measures (unit scopes).
* Calculates the multiplicative factor needed to convert a value from `fromMeasure` to `toMeasure`.
* @param fromMeasure The source measure unit.
* @param toMeasure The target measure unit.
* @returns The translation factor.
*/
export declare function getTranslationFactor(fromMeasure: SupportedMeasures, toMeasure: SupportedMeasures): number;
/**
* Adjusts the raw zoom level when the main scope is changed, aiming to maintain
* the same visual center point or numeric value representation on screen.
* @param currentZoom The current raw zoom level.
* @param oldMainMeasure The previous main measure.
* @param newMainMeasure The newly selected main measure.
* @returns The adjusted raw zoom level.
*/
export declare function getAdjustedZoomForMainScopeChange(currentZoom: number, oldMainMeasure: SupportedMeasures, newMainMeasure: SupportedMeasures): number;
/**
* Converts a raw value, assumed to be in NEUTRAL_SCOPE (meters), into its equivalent in the `currentScope`.
* This effectively gives the value as if it were measured in `currentScope` units while maintaining its physical magnitude relative to the neutral reference.
*
* @param value - The raw numeric value, assumed to be in NEUTRAL_SCOPE (e.g., meters).
* @param currentScope - The target scope (unit) to express the value in.
* @returns The value converted to `currentScope`, branded as `ScopedValue`.
*/
export declare const getNeutralScopedValue: (value: number, currentScope: Scope) => ScopedValue;
/**
* Constructs a `PrecisionValue` object from a value that is already scoped.
* A scoped value is typically expressed in `currentScope` units but is relative to `NEUTRAL_SCOPE`.
* This function converts this `newScopedValue` back to its original `RawValue` in its `providedScope`.
*
* @param newScopedValue - The value already expressed in `currentScope` units, relative to `NEUTRAL_SCOPE`.
* @param providedScope - The original scope (unit) the raw value should be in.
* @param currentScope - The scope (unit) in which `newScopedValue` is currently expressed.
* @returns A `PrecisionValue` object containing both the `scoped` (input) and calculated `value` (in `providedScope`).
*/
export declare const getPrecisionValueFromScoped: (newScopedValue: ScopedValue, providedScope: Scope, currentScope: Scope) => PrecisionValue;
/**
* Constructs a `PrecisionValue` object from a `RawValue`.
* It calculates the `scoped` representation of the `rawValue` (which is in `providedScope`)
* by converting it to the `currentScope`.
*
* @param rawValue - The raw numeric value in its original `providedScope`.
* @param providedScope - The original scope (unit) of the `rawValue`.
* @param currentScope - The target scope (unit) to express the `scoped` value in.
* @returns A `PrecisionValue` object containing the calculated `scoped` value and the original `value` (raw).
*/
export declare const getPrecisionValueFromRaw: (rawValue: RawValue, providedScope: Scope, currentScope: Scope) => PrecisionValue;
/**
* Converts a raw zoom value into a `ScopedZoomValue`.
* Due to the inverse perception of zoom (higher raw zoom means smaller represented units),
* this conversion is from `currentScope` to `NEUTRAL_SCOPE`.
* It essentially calculates how many `NEUTRAL_SCOPE` units are equivalent to one `currentScope` unit at the given raw zoom.
*
* @param rawZoomValue - The raw, dimensionless zoom factor.
* @param currentScope - The current active measurement scope.
* @returns The zoom value scoped relative to `NEUTRAL_SCOPE`, branded as `ScopedZoomValue`.
*/
export declare const getScopedZoomValue: (rawZoomValue: number, currentScope: SupportedMeasures) => ScopedZoomValue;
/**
* Calculates the real-world length a scale bar represents on the screen.
* `scaledZoom` is the value representing how many units of the current drawing scope one physical pixel covers.
* Multiplying this by the pixel width of the scale bar gives its total real-world length.
*
* @param scaleBarPxWidth - The width of the scale bar in physical pixels on the screen.
* @param scaledZoom - The current scaled zoom value (units of current drawing scope per physical pixel).
* @returns The real-world length the scale bar represents, in the units of the `currentScope` implied by `scaledZoom`.
*/
export declare const getScaledBarZoomValue: (scaleBarPxWidth: number, scaledZoom: ScaledZoom) => ScaledZoom;
/**
* Calculates the `ScaledZoom` value for a given `scopedZoom` in a `currentScope`.
* `scopedZoom` is the Z-axis zoom value in `currentScope` units, already relative to `NEUTRAL_SCOPE` (higher means more zoomed in).
* `ScaledZoom` (the return value) represents the distance in `currentScope` units
* that a single logical screen pixel covers on the X/Y drawing plane.
* This value is determined by the `scopedZoom` (which reflects the Z-axis viewing
* depth relative to `NEUTRAL_SCOPE`) and the `currentScope`.
*
* @param scopedZoom - The Z-axis zoom value, effectively `rawZoom` expressed in `NEUTRAL_SCOPE` units relative to `currentScope`.
* @param currentScope - The current active measurement scope.
* @returns The calculated `ScaledZoom` (units of `currentScope` per logical screen pixel).
*/
export declare const getScaledZoomValueForScope: (scopedZoom: ScopedZoomValue, currentScope: SupportedMeasures) => ScaledZoom;
/**
* Calculates the raw, dimensionless zoom factor from a `ScaledZoom` value.
* `ScaledZoom` represents the distance in `currentScope` units that a single
* logical screen pixel covers on the drawing plane.
* This function is the inverse of `getScaledZoomValueForScope`.
*
* @param scaledZoom - The scaled zoom value (units of `currentScope` per logical screen pixel on the drawing).
* @param currentScope - The scope (unit) in which `scaledZoom` is expressed.
* @returns The raw, dimensionless zoom factor, clamped within MIN_ZOOM and MAX_ZOOM.
*/
export declare const getRawZoomFromScaledZoom: (scaledZoom: ScaledZoom, currentScope: SupportedMeasures) => RawValue;
export declare const getScopedBezierPointFromDucPoint: (point: DucPoint) => GeometricPoint;
export declare const getPrecisionPointsFromScoped: (points: GeometricPoint[], targetScope: SupportedMeasures, currentScope: SupportedMeasures) => DucPoint[];