UNPKG

tweak-tools

Version:

Tweak your React projects until awesomeness

136 lines (135 loc) 6.02 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Joystick = void 0; const react_1 = __importStar(require("react")); const hooks_1 = require("../../hooks"); const utils_1 = require("../../utils"); const StyledJoystick_1 = require("./StyledJoystick"); const styles_1 = require("../../styles"); const UI_1 = require("../UI"); const hooks_2 = require("../../hooks"); function Joystick({ value, settings, onUpdate }) { const timeout = (0, react_1.useRef)(); const outOfBoundsX = (0, react_1.useRef)(0); const outOfBoundsY = (0, react_1.useRef)(0); const stepMultiplier = (0, react_1.useRef)(1); const [joystickShown, setShowJoystick] = (0, react_1.useState)(false); const [isOutOfBounds, setIsOutOfBounds] = (0, react_1.useState)(false); const [spanRef, set] = (0, hooks_2.useTransform)(); const joystickeRef = (0, react_1.useRef)(null); const playgroundRef = (0, react_1.useRef)(null); (0, react_1.useLayoutEffect)(() => { if (joystickShown) { const { top, left, width, height } = joystickeRef.current.getBoundingClientRect(); playgroundRef.current.style.left = left + width / 2 + 'px'; playgroundRef.current.style.top = top + height / 2 + 'px'; } }, [joystickShown]); const { keys: [v1, v2], joystick, } = settings; const yFactor = joystick === 'invertY' ? 1 : -1; // prettier-ignore const { [v1]: { step: stepV1 }, [v2]: { step: stepV2 } } = settings; const wpx = (0, styles_1.useTh)('sizes', 'joystickWidth'); const hpx = (0, styles_1.useTh)('sizes', 'joystickHeight'); const w = (parseFloat(wpx) * 0.8) / 2; const h = (parseFloat(hpx) * 0.8) / 2; const startOutOfBounds = (0, react_1.useCallback)(() => { if (timeout.current) return; setIsOutOfBounds(true); if (outOfBoundsX.current) set({ x: outOfBoundsX.current * w }); if (outOfBoundsY.current) set({ y: outOfBoundsY.current * -h }); timeout.current = window.setInterval(() => { onUpdate((v) => { const incX = stepV1 * outOfBoundsX.current * stepMultiplier.current; const incY = yFactor * stepV2 * outOfBoundsY.current * stepMultiplier.current; return Array.isArray(v) ? { [v1]: v[0] + incX, [v2]: v[1] + incY, } : { [v1]: v[v1] + incX, [v2]: v[v2] + incY, }; }); }, 16); }, [w, h, onUpdate, set, stepV1, stepV2, v1, v2, yFactor]); const endOutOfBounds = (0, react_1.useCallback)(() => { window.clearTimeout(timeout.current); timeout.current = undefined; setIsOutOfBounds(false); }, []); (0, react_1.useEffect)(() => { function setStepMultiplier(event) { stepMultiplier.current = (0, utils_1.multiplyStep)(event); } window.addEventListener('keydown', setStepMultiplier); window.addEventListener('keyup', setStepMultiplier); return () => { window.clearTimeout(timeout.current); window.removeEventListener('keydown', setStepMultiplier); window.removeEventListener('keyup', setStepMultiplier); }; }, []); const bind = (0, hooks_1.useDrag)(({ first, active, delta: [dx, dy], movement: [mx, my] }) => { if (first) setShowJoystick(true); const _x = (0, utils_1.clamp)(mx, -w, w); const _y = (0, utils_1.clamp)(my, -h, h); outOfBoundsX.current = Math.abs(mx) > Math.abs(_x) ? Math.sign(mx - _x) : 0; outOfBoundsY.current = Math.abs(my) > Math.abs(_y) ? Math.sign(_y - my) : 0; // @ts-expect-error let newX = value[v1]; // @ts-expect-error let newY = value[v2]; if (active) { if (!outOfBoundsX.current) { newX += dx * stepV1 * stepMultiplier.current; set({ x: _x }); } if (!outOfBoundsY.current) { newY -= yFactor * dy * stepV2 * stepMultiplier.current; set({ y: _y }); } if (outOfBoundsX.current || outOfBoundsY.current) startOutOfBounds(); else endOutOfBounds(); onUpdate({ [v1]: newX, [v2]: newY }); } else { setShowJoystick(false); outOfBoundsX.current = 0; outOfBoundsY.current = 0; set({ x: 0, y: 0 }); endOutOfBounds(); } }); return (react_1.default.createElement(StyledJoystick_1.JoystickTrigger, Object.assign({ ref: joystickeRef }, bind()), joystickShown && (react_1.default.createElement(UI_1.Portal, null, react_1.default.createElement(StyledJoystick_1.JoystickPlayground, { ref: playgroundRef, isOutOfBounds: isOutOfBounds }, react_1.default.createElement("div", null), react_1.default.createElement("span", { ref: spanRef })))))); } exports.Joystick = Joystick;