I have a React component that is supposed to handle pinch-zoom and two-finger panning on an SVG element. The pinch-zoom works as expected, but I've run into an issue with two-finger panning.
"use client";
import React, { useEffect, useRef, useMemo, useState } from "react";
import { useSpring, animated } from "@react-spring/web";
import {
createUseGesture,
dragAction,
pinchAction,
wheelAction,
} from "@use-gesture/react";
import { usePathname, useRouter } from "next/navigation";
import { useMotionValue } from "framer-motion";
import { set } from "zod";
const useGesture = createUseGesture([dragAction, pinchAction, wheelAction]);
export default function Gestures({ children }: { children: React.ReactNode }) {
const ref = useRef<HTMLDivElement>(null);
const innerRef = useRef<HTMLDivElement>(null);
const [isPinching, setIsPinching] = useState(false);
const [isOnWheelFired, setIsOnWheelFired] = useState(false);
const [style, api] = useSpring(() => ({
x: 0,
y: 0,
scale: 1,
rotateZ: 0,
}));
useGesture(
{
onDrag: ({ pinching, cancel, offset: [x, y] }) => {
if (pinching) return cancel();
api.start({ x, y });
},
onWheel: ({ direction: [dx, dy], offset: [x, y], first }) => {
console.log("ON WHEEL");
if (!isOnWheelFired) {
setIsOnWheelFired(true);
return;
}
api.start({ ...style, x: -x, y: -y });
// }
},
onWheelEnd: () => {
console.log("ON WHEEL END");
setIsOnWheelFired(false);
},
onPinchEnd: () => {
api.stop();
},
onPinch: ({
event,
memo,
origin: [pinchOriginX, pinchOriginY],
offset: [d],
}) => {
// event.preventDefault();
setIsPinching(true);
api.start({
x: style.x.get(),
y: style.y.get(),
scale: newScale,
});
return memo;
},
},
{
target: ref,
eventOptions: { passive: false },
}
);
return (
<div>
<div
ref={ref}
style={{
touchAction: "none",
position: "fixed",
width: "100vw",
height: "100vh",
}}
>
<animated.div
ref={innerRef}
style={{
...style,
touchAction: "none",
userSelect: "none",
MozUserSelect: "none",
// WebkitUserDrag: "none",
position: "absolute",
width: "100%",
height: "100%",
}}
>
{children}
</animated.div>
</div>
<div>
test x: {style.x.get()} y: {style.y.get()} scale: {style.scale.get()}
</div>
</div>
);
}
Any ideas on how to fix this?