Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 2x 2x 22x 22x 22x 22x 22x 22x | import React from "react"; import { useState } from "react"; import useInterval from "use-interval"; import { useSpring, animated } from "@react-spring/web"; import { useDrag } from "@use-gesture/react"; import { apiUpdateMoveRaw } from "./rest"; const speedOffset = 30; export const Joystick = (props) => { const [state, setState] = useState({active: false, position: {x: 0, y: 0}}); const [{ x, y }, set] = useSpring(() => ({ x: 0, y: 0 })); const bind = useDrag(async ({ active, movement: [mx, my] }) => { let distance = Math.sqrt(Math.pow(mx, 2) + Math.pow(my, 2)); if (active && distance > 100) { return; } let newPos = { x: mx, y: my }; setState({active: active, position: newPos}); set({ x: active ? mx : 0, y: active ? my : 0, immediate: active }); if (!active) { await apiUpdateMoveRaw(props.address, 0, 0).catch(error => console.log(error)); } }) const moveToSpeeds = () => { const dir = (128 * state.position.y / 200) * -1; const angle = (128 * state.position.x / 200) * -1; let leftSpeed = (dir + angle); let rightSpeed = (dir - angle); // Use speed offset if (leftSpeed > 0) { leftSpeed += speedOffset; } if (rightSpeed > 0) { rightSpeed += speedOffset; } if (leftSpeed < 0) { leftSpeed -= speedOffset; } if (rightSpeed < 0) { rightSpeed -= speedOffset; } // Clamp speeds to int8 bounds if (leftSpeed > 127) { leftSpeed = 127; } if (rightSpeed > 127) { rightSpeed = 127; } if (leftSpeed < -128) { leftSpeed = -128; } if (rightSpeed < -128) { rightSpeed = -128; } return { left: leftSpeed, right: rightSpeed }; }; useInterval(async () => { const speeds = moveToSpeeds(); await apiUpdateMoveRaw(props.address, speeds.left, speeds.right).catch(error => console.log(error)); }, state.active ? 100 : null); return ( <div style={{ height: '200px', width: '200px' }}> <div style={{ height: '200px', width: '200px', position: "absolute" }} role="region"> <svg style={{ height: '199px', width: '199px'}}> <circle cx={99} cy={99} r={98} fill="Lavender" opacity="80%" stroke="black" strokeWidth="1" /> </svg> </div> <div style={{ position: "relative", top: "50px", left: "50px" }}> <animated.div {...bind()} style={{ x, y, touchAction: 'none' }} role="button"> <svg style={{ height: '100px', width: '100px' }}> <defs> <radialGradient id={`joystickHandleGradient${props.address}`}> <stop offset="5%" stopColor="MediumSlateBlue" /> <stop offset="95%" stopColor="DarkSlateBlue" /> </radialGradient> </defs> <circle cx={50} cy={50} r={50} opacity="80%" fill={`url('#joystickHandleGradient${props.address}')`} /> </svg> </animated.div> </div> </div> ) } |