victory-native
Version:
[](https://commerce.nearform.com/open-source/victory-native/)
99 lines (90 loc) • 2.64 kB
text/typescript
import {
Gesture,
type PanGesture,
type PinchGesture,
} from "react-native-gesture-handler";
import { multiply4, scale, translate } from "@shopify/react-native-skia";
import type { PanGestureConfig } from "react-native-gesture-handler/lib/typescript/handlers/PanGestureHandler";
import { type ChartTransformState } from "../hooks/useChartTransformState";
type Dimension = "x" | "y";
export type PinchTransformGestureConfig = {
enabled?: boolean;
dimensions?: Dimension | Dimension[];
};
export const pinchTransformGesture = (
state: ChartTransformState,
_config: PinchTransformGestureConfig = {},
): PinchGesture => {
const defaults: PinchTransformGestureConfig = {
enabled: true,
dimensions: ["x", "y"],
};
const config = { ...defaults, ..._config };
const dimensions = Array.isArray(config.dimensions)
? config.dimensions
: [config.dimensions];
const scaleX = dimensions.includes("x");
const scaleY = dimensions.includes("y");
const pinch = Gesture.Pinch()
.onBegin((e) => {
state.offset.value = state.matrix.value;
state.origin.value = {
x: e.focalX,
y: e.focalY,
};
})
.onStart(() => {
state.zoomActive.value = true;
})
.onChange((e) => {
state.matrix.value = multiply4(
state.offset.value,
scale(
scaleX ? e.scale : 1,
scaleY ? e.scale : 1,
1,
state.origin.value,
),
);
})
.onEnd(() => {
state.zoomActive.value = false;
});
return pinch;
};
export type PanTransformGestureConfig = {
enabled?: boolean;
dimensions?: Dimension | Dimension[];
} & Pick<PanGestureConfig, "activateAfterLongPress">;
export const panTransformGesture = (
state: ChartTransformState,
_config: PanTransformGestureConfig = {},
): PanGesture => {
const defaults: PanTransformGestureConfig = {
enabled: true,
dimensions: ["x", "y"],
};
const config = { ...defaults, ..._config };
const dimensions = Array.isArray(config.dimensions)
? config.dimensions
: [config.dimensions];
const panX = dimensions.includes("x");
const panY = dimensions.includes("y");
const pan = Gesture.Pan()
.onStart(() => {
state.panActive.value = true;
})
.onChange((e) => {
state.matrix.value = multiply4(
translate(panX ? e.changeX : 0, panY ? e.changeY : 0, 0),
state.matrix.value,
);
})
.onEnd(() => {
state.panActive.value = false;
});
if (config.activateAfterLongPress !== undefined) {
pan.activateAfterLongPress(config.activateAfterLongPress);
}
return pan;
};