mirror of
https://github.com/minagawah/mikaboshi.git
synced 2026-03-27 08:28:29 +07:00
140 lines
3.1 KiB
JavaScript
140 lines
3.1 KiB
JavaScript
import { compose } from 'ramda';
|
|
import { PIE_UNIT_HALF } from '@/constants';
|
|
|
|
export const int = Math.trunc;
|
|
|
|
export const noop = () => {};
|
|
|
|
export const fixed =
|
|
(decimals = 3) =>
|
|
n => {
|
|
const place = Math.pow(10, decimals);
|
|
return int(n * place) / place;
|
|
};
|
|
|
|
// export const to_fixed = (n, decimals = 3) => fixed(decimals)(n);
|
|
|
|
export const capitalize = s => s[0].toUpperCase() + s.slice(1);
|
|
|
|
export const gen_code_4 = () =>
|
|
Math.floor((1 + Math.random()) * 0x10000)
|
|
.toString(16)
|
|
.substring(1);
|
|
|
|
export const gen_code_12 = () =>
|
|
`${gen_code_4()}${gen_code_4()}${gen_code_4()}`;
|
|
|
|
export const rad_to_deg = rad => rad * (180 / Math.PI);
|
|
export const deg_to_rad = deg => deg * (Math.PI / 180);
|
|
|
|
export const normalize_degree = deg => ((deg % 360) + 360) % 360;
|
|
export const normalize_angle = normalize_degree;
|
|
export const normalize_radian = compose(
|
|
deg_to_rad,
|
|
normalize_degree,
|
|
rad_to_deg
|
|
);
|
|
|
|
export const get_position = (rad, radius = 1, center = { x: 0, y: 0 }) => ({
|
|
deg: normalize_degree(rad_to_deg(rad)),
|
|
x: center.x + Math.cos(rad) * radius,
|
|
y: center.y + Math.sin(rad) * radius,
|
|
});
|
|
|
|
// Compared to `get_position`, this function uses
|
|
// `Math.sin()` for `x`, and `Math.cos()` for `y`.
|
|
export const get_position_clock = (
|
|
rad,
|
|
radius = 1,
|
|
center = { x: 0, y: 0 }
|
|
) => ({
|
|
deg: normalize_degree(rad_to_deg(rad)),
|
|
x: center.x + Math.sin(rad) * radius,
|
|
y: center.y - Math.cos(rad) * radius,
|
|
});
|
|
|
|
export const euler_from_quaternion = (q = []) => {
|
|
/*
|
|
* alpha
|
|
* - Yew
|
|
* - Rotation around Z-axis (a ray coming out of your phone)
|
|
* - Screen-face rotation (like a car handle when driving)
|
|
*/
|
|
const alpha = normalize_degree(
|
|
rad_to_deg(
|
|
Math.atan2(
|
|
2 * q[0] * q[1] + 2 * q[2] * q[3],
|
|
1 - 2 * q[1] * q[1] - 2 * q[2] * q[2]
|
|
)
|
|
)
|
|
);
|
|
|
|
/*
|
|
* gamma
|
|
* - Roll
|
|
* - Rotation around Y-axis (phone's vertical axis)
|
|
* - Horizontal tilt (left-right tilt)
|
|
*/
|
|
const gamma = normalize_degree(
|
|
rad_to_deg(
|
|
Math.atan2(
|
|
2 * (q[3] * q[0] + q[1] * q[2]),
|
|
1 - 2 * (q[0] * q[0] + q[1] * q[1])
|
|
)
|
|
)
|
|
);
|
|
|
|
return [alpha, gamma];
|
|
};
|
|
|
|
export const get_utc_offset_in_hours = dt =>
|
|
int(Math.floor(dt.utcOffset() / 60));
|
|
|
|
export const str_to_hex = str => parseInt(str.slice(1), 16);
|
|
|
|
export const pad =
|
|
(digits = 2) =>
|
|
(n = 0) =>
|
|
n.toString().padStart(digits, '0');
|
|
|
|
export const is_leap_year = year => {
|
|
if (year % 4 == 0) {
|
|
if (year % 100 == 0) {
|
|
return year % 400 == 0;
|
|
} else {
|
|
return true;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
export const is_iOS =
|
|
navigator.userAgent.match(/(iPod|iPhone|iPad)/) &&
|
|
navigator.userAgent.match(/AppleWebKit/);
|
|
|
|
let time = Date.now();
|
|
|
|
export const debounce = (f, delay) => {
|
|
let timeout = null;
|
|
let args = null;
|
|
|
|
const g = () => {
|
|
f.apply(null, args);
|
|
time = Date.now();
|
|
};
|
|
|
|
return function () {
|
|
args = arguments;
|
|
|
|
if (Date.now() >= time + delay) {
|
|
// Execute if the time has passed.
|
|
g();
|
|
} else {
|
|
// Cancel the previous ones, and execute only the last one.
|
|
!!timeout && clearTimeout(timeout);
|
|
timeout = setTimeout(g, delay);
|
|
}
|
|
};
|
|
};
|