react-spring#config TypeScript Examples
The following examples show how to use
react-spring#config.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DragControls.tsx From spacesvr with MIT License | 5 votes |
/**
* DragControls allows for a click-and-drag control
* of the camera
*
* @param props
* @constructor
*/
export function DragControls() {
const originEuler = useRef<Euler>(new Euler(0, 0, 0, "YXZ"));
const setEuler = useRef<Euler>(new Euler(0, 0, 0, "YXZ"));
const mouseDownPos = useRef<Vector2>(new Vector2(0, 0));
const dragging = useRef(false);
const camera = useThree((state) => state.camera);
const { containerRef } = useEnvironment();
const [xyz, setXYZ] = useState([0, 0, 0]);
const { x, y, z } = useSpring({
x: xyz[0],
y: xyz[1],
z: xyz[2],
config: { ...config.default, precision: 0.0001 },
});
useFrame(() => {
if (setEuler.current) {
setEuler.current.set(x.get(), y.get(), z.get());
camera.quaternion.setFromEuler(setEuler.current);
}
});
const getNewEuler = (
dragX: number,
dragY: number,
isHover?: boolean
): Euler => {
const newEuler = originEuler.current.clone();
const moveX = dragX - mouseDownPos.current.x;
const moveY = dragY - mouseDownPos.current.y;
const SENSITIVITY = isHover ? HOVER_SENSITIVITY : DRAG_SENSITIVITY;
newEuler.setFromQuaternion(camera.quaternion);
newEuler.y = originEuler.current.y - (moveX * SENSITIVITY.x) / 100;
newEuler.x = originEuler.current.x - (moveY * SENSITIVITY.y) / 100;
// newEuler.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, newEuler.x));
return newEuler;
};
// touch move scripts
const onMouseDown = (ev: MouseEvent) => {
dragging.current = true;
mouseDownPos.current.set(ev.clientX, ev.clientY);
containerRef?.current?.classList.add("grabbing");
};
const onMouseMove = (ev: MouseEvent) => {
const newEuler = getNewEuler(ev.clientX, ev.clientY, !dragging.current);
setXYZ(newEuler.toArray());
};
const onMouseUp = (ev: MouseEvent) => {
dragging.current = false;
originEuler.current = getNewEuler(ev.clientX, ev.clientY);
mouseDownPos.current.set(ev.clientX, ev.clientY);
containerRef?.current?.classList.remove("grabbing");
};
useEffect(() => {
document.addEventListener("mousedown", onMouseDown);
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
return () => {
document.removeEventListener("mousedown", onMouseDown);
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
};
}, [containerRef]);
return null;
}
Example #2
Source File: GyroControls.tsx From spacesvr with MIT License | 4 votes |
GyroControls = (props: GyroControlsProps) => {
const { fallback } = props;
const camera = useThree((state) => state.camera);
const [controls, setControls] = useState<DeviceOrientationControls>();
const [enableGyro, setEnableGyro] = useState(false);
const [alphaVal, setAlphaVal] = useState(0);
// dragging for y axis offset
const touchStartPos = useRef<Touch>(DefaultTouch);
const currentOffset = useRef(0);
const { alpha } = useSpring({
alpha: alphaVal,
config: { ...config.default, precision: 0.001 },
});
// try to prompt user for device controls
useEffect(() => {
if (!controls) {
const func = () => {
const cont = new DeviceOrientationControls(camera);
cont.enabled = false; // set to disabled in case they're not working yet
setControls(cont);
};
window.addEventListener("click", func);
return () => {
window.removeEventListener("click", func);
};
}
}, [controls]);
useFrame(() => {
if (controls && !enableGyro) {
// check if an event has been received yet
if (Object.keys(controls.deviceOrientation).length !== 0) {
setEnableGyro(true);
controls.enabled = true;
}
}
if (controls) {
controls.alphaOffset = -alpha.get() * ALPHA_SENSITIVITY;
controls.update();
}
});
// touch move scripts
const onTouchStart = (ev: TouchEvent) => {
if (touchStartPos.current.id !== -1) {
return;
}
if (tappedNipple(ev)) {
touchStartPos.current = DefaultTouch;
return;
}
// get last in list (most recent touch) to not confuse with movement
const touchIndex = ev.touches.length - 1;
const { clientX, clientY, identifier: id } = ev.touches[touchIndex];
touchStartPos.current = { pos: new Vector2(clientX, clientY), id };
};
const onTouchMove = (ev: TouchEvent) => {
const touch = getCurrentTouch(touchStartPos.current.id, ev.touches);
if (!touch) {
return;
}
const extraOffset = touch.clientX - touchStartPos.current.pos.x;
setAlphaVal(currentOffset.current + extraOffset);
};
const onTouchEnd = (ev: TouchEvent) => {
const touch = getCurrentTouch(touchStartPos.current.id, ev.changedTouches);
if (!touch) {
return;
}
const finalOffset = touch.clientX - touchStartPos.current.pos.x;
setAlphaVal(currentOffset.current + finalOffset);
currentOffset.current += finalOffset;
touchStartPos.current.id = -1;
};
// register touch events
useEffect(() => {
document.addEventListener("touchstart", onTouchStart);
document.addEventListener("touchmove", onTouchMove);
document.addEventListener("touchend", onTouchEnd);
return () => {
document.removeEventListener("touchstart", onTouchStart);
document.removeEventListener("touchmove", onTouchMove);
document.removeEventListener("touchend", onTouchEnd);
};
}, []);
if (!enableGyro) {
return <>{fallback}</>;
}
return null;
}