UNPKG

@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
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 }; } ;