react-native-zoom-toolkit
Version:
Smoothly zoom any image, video or component you want!
163 lines (157 loc) • 5.81 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.usePinchCommons = void 0;
var _react = require("react");
var _reactNativeReanimated = require("react-native-reanimated");
var _clamp = require("../utils/clamp");
var _pinchTransform = require("../utils/pinchTransform");
var _types = require("../types");
const usePinchCommons = options => {
const {
container,
detectorTranslate,
detectorScale,
translate,
offset,
delta,
scale,
scaleOffset,
minScale,
maxScale,
scaleMode,
pinchCenteringMode,
allowPinchPanning,
origin,
boundFn,
userCallbacks
} = options;
const pinchClamp = pinchCenteringMode === _types.PinchCenteringMode.CLAMP;
const scaleClamp = scaleMode === _types.ScaleMode.CLAMP;
// This value is used to trigger the onGestureEnd callback as a gimmick to avoid unneccesary calculations.
const gestureEnd = (0, _reactNativeReanimated.useSharedValue)(0);
const [gesturesEnabled, setGesturesEnabled] = (0, _react.useState)(true);
const switchGesturesState = value => {
if (scaleMode !== _types.ScaleMode.BOUNCE) return;
setGesturesEnabled(value);
};
const onPinchStart = e => {
'worklet';
(0, _reactNativeReanimated.runOnJS)(switchGesturesState)(false);
userCallbacks.onPinchStart && (0, _reactNativeReanimated.runOnJS)(userCallbacks.onPinchStart)(e);
(0, _reactNativeReanimated.cancelAnimation)(translate.x);
(0, _reactNativeReanimated.cancelAnimation)(translate.y);
(0, _reactNativeReanimated.cancelAnimation)(detectorTranslate.x);
(0, _reactNativeReanimated.cancelAnimation)(detectorTranslate.y);
(0, _reactNativeReanimated.cancelAnimation)(scale);
(0, _reactNativeReanimated.cancelAnimation)(detectorScale);
origin.x.value = e.focalX - container.width.value / 2;
origin.y.value = e.focalY - container.height.value / 2;
offset.x.value = translate.x.value;
offset.y.value = translate.y.value;
scaleOffset.value = scale.value;
};
const onPinchUpdate = e => {
'worklet';
let toScale = e.scale * scaleOffset.value;
if (scaleClamp) toScale = (0, _clamp.clamp)(toScale, minScale, maxScale.value);
delta.x.value = e.focalX - container.width.value / 2 - origin.x.value;
delta.y.value = e.focalY - container.height.value / 2 - origin.y.value;
const {
x: toX,
y: toY
} = (0, _pinchTransform.pinchTransform)({
toScale: toScale,
fromScale: scaleOffset.value,
origin: {
x: origin.x.value,
y: origin.y.value
},
offset: {
x: offset.x.value,
y: offset.y.value
},
delta: {
x: allowPinchPanning ? delta.x.value * scaleOffset.value : 0,
y: allowPinchPanning ? delta.y.value * scaleOffset.value : 0
}
});
const {
x: boundX,
y: boundY
} = boundFn(toScale);
const clampedX = (0, _clamp.clamp)(toX, -1 * boundX, boundX);
const clampedY = (0, _clamp.clamp)(toY, -1 * boundY, boundY);
translate.x.value = pinchClamp ? clampedX : toX;
translate.y.value = pinchClamp ? clampedY : toY;
scale.value = toScale;
};
const reset = (toX, toY, toScale) => {
'worklet';
(0, _reactNativeReanimated.cancelAnimation)(translate.x);
(0, _reactNativeReanimated.cancelAnimation)(translate.y);
(0, _reactNativeReanimated.cancelAnimation)(scale);
detectorTranslate.x.value = translate.x.value;
detectorTranslate.y.value = translate.y.value;
detectorScale.value = scale.value;
detectorTranslate.x.value = (0, _reactNativeReanimated.withTiming)(toX);
detectorTranslate.y.value = (0, _reactNativeReanimated.withTiming)(toY);
detectorScale.value = (0, _reactNativeReanimated.withTiming)(toScale);
const areTXNotEqual = translate.x.value !== toX;
const areTYNotEqual = translate.y.value !== toY;
const areScalesNotEqual = scale.value !== toScale;
const toValue = areTXNotEqual || areTYNotEqual || areScalesNotEqual ? 1 : 0;
translate.x.value = (0, _reactNativeReanimated.withTiming)(toX);
translate.y.value = (0, _reactNativeReanimated.withTiming)(toY);
scale.value = (0, _reactNativeReanimated.withTiming)(toScale, undefined, finished => {
finished && (0, _reactNativeReanimated.runOnJS)(switchGesturesState)(true);
});
gestureEnd.value = (0, _reactNativeReanimated.withTiming)(toValue, undefined, finished => {
gestureEnd.value = 0;
if (finished && userCallbacks.onGestureEnd !== undefined) {
(0, _reactNativeReanimated.runOnJS)(userCallbacks.onGestureEnd)();
}
});
};
const onPinchEnd = e => {
'worklet';
userCallbacks.onPinchEnd && (0, _reactNativeReanimated.runOnJS)(userCallbacks.onPinchEnd)(e);
const toScale = (0, _clamp.clamp)(scale.value, minScale, maxScale.value);
const scaleDiff = scaleMode === _types.ScaleMode.BOUNCE && scale.value > maxScale.value ? Math.max(0, scaleOffset.value - (scale.value - scaleOffset.value) / 2) : 0;
const {
x,
y
} = (0, _pinchTransform.pinchTransform)({
toScale: toScale,
fromScale: scale.value,
origin: {
x: origin.x.value,
y: origin.y.value
},
offset: {
x: translate.x.value,
y: translate.y.value
},
delta: {
x: 0,
y: allowPinchPanning ? -delta.y.value * scaleDiff : 0
}
});
const {
x: boundX,
y: boundY
} = boundFn(toScale);
const toX = (0, _clamp.clamp)(x, -1 * boundX, boundX);
const toY = (0, _clamp.clamp)(y, -1 * boundY, boundY);
reset(toX, toY, toScale);
};
return {
gesturesEnabled,
onPinchStart,
onPinchUpdate,
onPinchEnd
};
};
exports.usePinchCommons = usePinchCommons;
//# sourceMappingURL=usePinchCommons.js.map