@trap_stevo/legendarybuilderproreact-ui
Version:
The legendary UI & utility API that makes your application a legendary application. ~ Created by Steven Compton
257 lines • 7.91 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import { useEffect, useRef, useState } from "react";
function getVector(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
var length = Math.hypot(dx, dy);
return length === 0 ? {
x: 0,
y: 0,
magnitude: 0
} : {
x: dx / length,
y: dy / length,
magnitude: length
};
}
;
function getPolarCoords(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
var radius = Math.hypot(dx, dy);
var thetaRadians = Math.atan2(dy, dx);
var thetaDegrees = thetaRadians * 180 / Math.PI;
var theta360 = (thetaDegrees + 360) % 360;
return {
radius: radius,
thetaRadians: thetaRadians,
thetaDegrees: thetaDegrees,
theta360: theta360
};
}
;
function smoothLerp(a, b, factor) {
return a + (b - a) * factor;
}
;
function smoothVector(from, to, factor) {
return {
x: smoothLerp(from.x, to.x, factor),
y: smoothLerp(from.y, to.y, factor)
};
}
;
function parseGranularity(input) {
if (typeof input === "number") {
return 360 / input;
}
if (typeof input === "string") {
if (input.endsWith("dir")) {
return parseInt(input) || 16;
}
if (input.endsWith("deg")) {
return Math.round(360 / parseFloat(input));
}
}
return 16;
}
;
function defaultLabelForSegment(segment, totalSegments) {
var arrows = ["→", "↘", "↓", "↙", "←", "↖", "↑", "↗"];
return totalSegments === 8 ? arrows[segment % 8] : "".concat((segment * 360 / totalSegments).toFixed(1), "\xB0");
}
;
function classifyByGranularity(angle360, divisions) {
var customLabels = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var segment = Math.round(angle360 / (360 / divisions)) % divisions;
return Array.isArray(customLabels) && customLabels.length === divisions ? customLabels[segment] : defaultLabelForSegment(segment, divisions);
}
;
function areVectorsEqual(v1, v2) {
var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0.001;
return Math.abs(v1.x - v2.x) < threshold && Math.abs(v1.y - v2.y) < threshold;
}
;
function areAnglesEqual(a1, a2) {
var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0.1;
return Math.abs(a1 - a2) < threshold;
}
;
export function ArrivedAtCoordinate(from, to) {
var threshold = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
var dx = Math.abs(from.x - to.x);
var dy = Math.abs(from.y - to.y);
return dx <= threshold && dy <= threshold;
}
;
export function GetDirectionToTarget(from, to) {
var dx = to.x - from.x;
var dy = from.y - to.y;
var radians = Math.atan2(dy, dx);
var degrees = radians * 180 / Math.PI;
return (degrees + 360) % 360;
}
;
export function useCursorDirection() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _options$origin = options.origin,
origin = _options$origin === void 0 ? {
x: window.innerWidth / 2,
y: window.innerHeight / 2
} : _options$origin,
_options$minDistance = options.minDistance,
minDistance = _options$minDistance === void 0 ? 5 : _options$minDistance,
_options$smooth = options.smooth,
smooth = _options$smooth === void 0 ? true : _options$smooth,
_options$lerpFactor = options.lerpFactor,
lerpFactor = _options$lerpFactor === void 0 ? 0.15 : _options$lerpFactor,
_options$directionGra = options.directionGranularity,
directionGranularity = _options$directionGra === void 0 ? "16dir" : _options$directionGra,
_options$customLabels = options.customLabels,
customLabels = _options$customLabels === void 0 ? null : _options$customLabels;
var _useState = useState({
radius: 0,
thetaRadians: 0,
thetaDegrees: 0,
theta360: 0
}),
_useState2 = _slicedToArray(_useState, 2),
polar = _useState2[0],
setPolar = _useState2[1];
var _useState3 = useState({
x: 0,
y: 0
}),
_useState4 = _slicedToArray(_useState3, 2),
mousePosition = _useState4[0],
setMousePosition = _useState4[1];
var _useState5 = useState({
x: 0,
y: 0
}),
_useState6 = _slicedToArray(_useState5, 2),
cartesian = _useState6[0],
setCartesian = _useState6[1];
var _useState7 = useState(null),
_useState8 = _slicedToArray(_useState7, 2),
directionLabel = _useState8[0],
setDirectionLabel = _useState8[1];
var vectorRef = useRef({
x: 0,
y: 0
});
var touchingRef = useRef(false);
var originRef = useRef(origin);
var lockRef = useRef(false);
var labelRef = useRef(null);
var angleRef = useRef(0);
useEffect(function () {
originRef.current = origin;
}, [origin]);
useEffect(function () {
function safeUpdate(x, y) {
if (lockRef.current) {
return;
}
lockRef.current = true;
requestAnimationFrame(function () {
lockRef.current = false;
setMousePosition({
x: x,
y: y
});
var _getPolarCoords = getPolarCoords(originRef.current.x, originRef.current.y, x, y),
radius = _getPolarCoords.radius,
thetaRadians = _getPolarCoords.thetaRadians,
thetaDegrees = _getPolarCoords.thetaDegrees,
theta360 = _getPolarCoords.theta360;
if (radius < minDistance) {
if (polar.radius !== 0) {
setPolar({
radius: 0,
thetaRadians: 0,
thetaDegrees: 0,
theta360: 0
});
setCartesian({
x: 0,
y: 0
});
setDirectionLabel(null);
}
return;
}
var rawVec = getVector(originRef.current.x, originRef.current.y, x, y);
var vec = smooth ? smoothVector(vectorRef.current, rawVec, lerpFactor) : rawVec;
if (!areVectorsEqual(vec, vectorRef.current)) {
vectorRef.current = vec;
setCartesian(vec);
}
if (!areAnglesEqual(theta360, angleRef.current)) {
angleRef.current = theta360;
setPolar({
radius: radius,
thetaRadians: thetaRadians,
thetaDegrees: thetaDegrees,
theta360: theta360
});
var divisions = parseGranularity(directionGranularity);
var label = classifyByGranularity(theta360, divisions, customLabels);
if (label !== labelRef.current) {
labelRef.current = label;
setDirectionLabel(label);
}
}
});
}
function handleMouseMove(e) {
if (!touchingRef.current) {
safeUpdate(e.clientX, e.clientY);
}
}
function handleTouchStart() {
touchingRef.current = true;
}
function handleTouchMove(e) {
var touch = e.touches[0];
if (touch) {
safeUpdate(touch.clientX, touch.clientY);
}
}
function handleTouchEnd() {
touchingRef.current = false;
setPolar({
radius: 0,
thetaRadians: 0,
thetaDegrees: 0,
theta360: 0
});
setMousePosition({
x: 0,
y: 0
});
setCartesian({
x: 0,
y: 0
});
setDirectionLabel(null);
}
window.addEventListener("touchstart", handleTouchStart);
window.addEventListener("mousemove", handleMouseMove);
window.addEventListener("touchmove", handleTouchMove);
window.addEventListener("touchend", handleTouchEnd);
return function () {
window.removeEventListener("touchstart", handleTouchStart);
window.removeEventListener("mousemove", handleMouseMove);
window.removeEventListener("touchmove", handleTouchMove);
window.removeEventListener("touchend", handleTouchEnd);
};
}, []);
return {
directionLabel: directionLabel,
mousePosition: mousePosition,
cartesian: cartesian,
polar: polar
};
}
;