toosoon-utils
Version:
Utility functions & classes
113 lines (112 loc) • 3.46 kB
JavaScript
import { PI, RAD2DEG, DEG2RAD } from './constants';
/**
* Convert a radians angle into degrees
*
* @param {number} radians Angle in radians
* @returns {number} Angle in degrees
*/
export function toDegrees(radians) {
return radians * RAD2DEG;
}
/**
* Convert a degrees angle into radians
*
* @param {number} degrees Angle in degrees
* @returns {number} Angle in radians
*/
export function toRadians(degrees) {
return degrees * DEG2RAD;
}
/**
* Compute the angle (in radians) from a point to another
*
* @param {number} x1 X-axis coordinate of the start point
* @param {number} y1 Y-axis coordinate of the start point
* @param {number} x2 X-axis coordinate of the end point
* @param {number} y2 Y-axis coordinate of the end point
* @returns {number} Computed angle (in radians)
*/
export function angle(x1, y1, x2, y2) {
return Math.atan2(y2 - y1, x2 - x1);
}
/**
* Compute the closest angle (in radians) between two angles
*
* @param {number} startAngle Start angle (in radians)
* @param {number} endAngle End angle (in radians)
* @returns {number} Closest angle (in radians)
*/
export function closestAngle(startAngle, endAngle) {
const delta = endAngle - startAngle;
return delta > PI ? endAngle - 2 * PI : endAngle < -PI ? delta + 2 * PI : endAngle;
}
/**
* Compute the distance between two points
*
* @param {number} x1 X-axis coordinate of the start point
* @param {number} y1 Y-axis coordinate of the start point
* @param {number} x2 X-axis coordinate of the end point
* @param {number} y2 Y-axis coordinate of the end point
* @returns {number} Computed distance
*/
export function distance(x1, y1, x2, y2) {
const dx = x1 - x2;
const dy = y1 - y2;
return Math.sqrt(dx * dx + dy * dy);
}
/**
* Compute the length of the diagonal of a rectangle
*
* @param {number} width Width of the rectangle
* @param {number} height Height of the rectangle
* @returns {number} Diagonal length
*/
export function diagonal(width, height) {
return Math.sqrt(width * width + height * height);
}
/**
* Make a target fit a container
*
* @param {FitInput} target Dimensions of the target
* @param {FitInput} container Dimensions of the container
* @param {string} mode Can be 'contain' | 'cover'
* @returns {FitOutput}
*/
function fit(target, container, mode) {
const ratioWidth = container.width / target.width;
const ratioHeight = container.height / target.height;
let scale;
if (mode === 'contain') {
scale = ratioWidth < ratioHeight ? ratioWidth : ratioHeight;
}
else {
scale = ratioWidth > ratioHeight ? ratioWidth : ratioHeight;
}
return {
left: (container.width - target.width * scale) >> 1,
top: (container.height - target.height * scale) >> 1,
width: target.width * scale,
height: target.height * scale,
scale
};
}
/**
* Make a target fit a container (cover mode)
*
* @param {FitInput} target Dimensions of the target
* @param {FitInput} container Dimensions of the container
* @returns {FitOutput}
*/
export function cover(target, container) {
return fit(target, container, 'cover');
}
/**
* Make a target fit a container (contain mode)
*
* @param {FitInput} target Dimensions of the target
* @param {FitInput} container Dimensions of the container
* @returns {FitOutput}
*/
export function contain(target, container) {
return fit(target, container, 'contain');
}