@mantine/hooks
Version:
A collection of 50+ hooks for state and UI management
102 lines (101 loc) • 3.46 kB
JavaScript
"use client";
const require_clamp = require("../utils/clamp/clamp.cjs");
let react = require("react");
//#region packages/@mantine/hooks/src/use-radial-move/use-radial-move.ts
function radiansToDegrees(radians) {
return radians * (180 / Math.PI);
}
function getElementCenter(element) {
const rect = element.getBoundingClientRect();
return [rect.left + rect.width / 2, rect.top + rect.height / 2];
}
function getAngle(coordinates, element) {
const center = getElementCenter(element);
const x = coordinates[0] - center[0];
const y = coordinates[1] - center[1];
return 360 - (radiansToDegrees(Math.atan2(x, y)) + 180);
}
function toFixed(value, digits) {
return parseFloat(value.toFixed(digits));
}
function getDigitsAfterDot(value) {
return value.toString().split(".")[1]?.length || 0;
}
function normalizeRadialValue(degree, step) {
const clamped = require_clamp.clamp(degree, 0, 360);
const high = Math.ceil(clamped / step);
const low = Math.round(clamped / step);
return toFixed(high >= clamped / step ? high * step === 360 ? 0 : high * step : low * step, getDigitsAfterDot(step));
}
function useRadialMove(onChange, { step = .01, onChangeEnd, onScrubStart, onScrubEnd } = {}) {
const mounted = (0, react.useRef)(false);
const [active, setActive] = (0, react.useState)(false);
(0, react.useEffect)(() => {
mounted.current = true;
}, []);
return {
ref: (0, react.useCallback)((node) => {
const update = (event, done = false) => {
if (node) {
node.style.userSelect = "none";
const newValue = normalizeRadialValue(getAngle([event.clientX, event.clientY], node), step || 1);
onChange(newValue);
done && onChangeEnd?.(newValue);
}
};
const beginTracking = () => {
onScrubStart?.();
setActive(true);
document.addEventListener("mousemove", handleMouseMove, false);
document.addEventListener("mouseup", handleMouseUp, false);
document.addEventListener("touchmove", handleTouchMove, { passive: false });
document.addEventListener("touchend", handleTouchEnd, false);
};
const endTracking = () => {
onScrubEnd?.();
setActive(false);
document.removeEventListener("mousemove", handleMouseMove, false);
document.removeEventListener("mouseup", handleMouseUp, false);
document.removeEventListener("touchmove", handleTouchMove, false);
document.removeEventListener("touchend", handleTouchEnd, false);
};
const onMouseDown = (event) => {
beginTracking();
update(event);
};
const handleMouseMove = (event) => {
update(event);
};
const handleMouseUp = (event) => {
update(event, true);
endTracking();
};
const handleTouchMove = (event) => {
event.preventDefault();
update(event.touches[0]);
};
const handleTouchEnd = (event) => {
update(event.changedTouches[0], true);
endTracking();
};
const handleTouchStart = (event) => {
event.preventDefault();
beginTracking();
update(event.touches[0]);
};
node?.addEventListener("mousedown", onMouseDown);
node?.addEventListener("touchstart", handleTouchStart, { passive: false });
return () => {
if (node) {
node.removeEventListener("mousedown", onMouseDown);
node.removeEventListener("touchstart", handleTouchStart);
}
};
}, [onChange]),
active
};
}
//#endregion
exports.normalizeRadialValue = normalizeRadialValue;
exports.useRadialMove = useRadialMove;
//# sourceMappingURL=use-radial-move.cjs.map