Files
luminance/src/util.ts
T

114 lines
2.6 KiB
TypeScript

import type { RefObject } from "react";
import { Hex } from "colorlib";
import type { CartesianSpace, Range } from "./types";
import { Direction } from "./types";
export function minmax(number: number, min: number, max: number) {
return Math.min(max, Math.max(min, number));
}
export function isTouchEvent(event: Event): event is TouchEvent {
return "touches" in event;
}
export function isLeftMouseButton(buttonsValue: number) {
return buttonsValue === 1;
}
export function extractEventCoordinates(event: MouseEvent | TouchEvent): {
clientX: number;
clientY: number;
} {
if (isTouchEvent(event)) {
return {
clientX: event.touches[0].clientX,
clientY: event.touches[0].clientY,
};
}
return {
clientX: event.clientX,
clientY: event.clientY,
};
}
export function setMeasurements(
ref: RefObject<HTMLElement | null>,
setOrigin: (newOrigin: CartesianSpace) => void,
setDimensions: (newDimensions: CartesianSpace) => void,
) {
const el = ref.current;
if (el) {
const rect = el.getBoundingClientRect();
setOrigin({ x: rect.left, y: rect.top });
setDimensions({ x: rect.width, y: rect.height });
}
}
export function valueToPosition(
value: number,
maxPosition: number,
valueRange: Range,
) {
if (maxPosition <= 0 || !isFinite(value)) return 0;
const rangeSpan = Math.abs(valueRange.min) + Math.abs(valueRange.max);
if (rangeSpan === 0) return 0;
const position = Math.round(
maxPosition *
((value + Math.abs(valueRange.min)) /
(Math.abs(valueRange.min) + Math.abs(valueRange.max))),
);
return position;
}
export function positionToValue(
position: number,
maxPosition: number,
valueRange: Range,
) {
if (maxPosition <= 0 || !isFinite(position)) return valueRange.min;
const rangeSpan = Math.abs(valueRange.min) + Math.abs(valueRange.max);
if (rangeSpan === 0) return valueRange.min;
const value =
(position / maxPosition) *
(Math.abs(valueRange.min) + Math.abs(valueRange.max)) -
Math.abs(valueRange.min);
return value;
}
export function chooseValueByDirection(
direction: Direction,
xValue: number,
yValue: number,
) {
return direction === Direction.HORIZONTAL ? xValue : yValue;
}
export function roundTo(
value: number,
decimals: number = 0,
direction: "up" | "down" | null = null,
) {
const factor = Math.pow(10, decimals);
switch (direction) {
case "up":
return Math.ceil(value * factor) / factor;
case "down":
return Math.floor(value * factor) / factor;
default:
return Math.round(value * factor) / factor;
}
}
export function formatCssRgb(hex: Hex) {
return `rgb(${hex.r},${hex.g},${hex.b})`;
}