react-native-zoom-toolkit
Version:
Most complete set of pinch to zoom utilites for React Native
158 lines (156 loc) • 7.7 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireDefault(require("react"));
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
var _reactNativeGestureHandler = require("react-native-gesture-handler");
var _useVector = require("../../commons/hooks/useVector");
var _useSizeVector = require("../../commons/hooks/useSizeVector");
var _resizeToAspectRatio = require("../../commons/utils/resizeToAspectRatio");
var _withSnapbackValidation = _interopRequireDefault(require("../../commons/hoc/withSnapbackValidation"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const DEFAULT_HITSLOP = {
vertical: 0,
horizontal: 0
};
const SnapbackZoom = ({
children,
hitSlop = DEFAULT_HITSLOP,
resizeConfig,
timingConfig,
gesturesEnabled = true,
longPressDuration = 500,
scrollRef,
onTap,
onDoubleTap,
onPinchStart,
onPinchEnd,
onLongPress,
onUpdate,
onGestureEnd
}) => {
const containerRef = (0, _reactNativeReanimated.useAnimatedRef)();
const translate = (0, _useVector.useVector)(0, 0);
const scale = (0, _reactNativeReanimated.useSharedValue)(1);
const position = (0, _useVector.useVector)(0, 0);
const origin = (0, _useVector.useVector)(0, 0);
const initialFocal = (0, _useVector.useVector)(0, 0);
const currentFocal = (0, _useVector.useVector)(0, 0);
const containerSize = (0, _useSizeVector.useSizeVector)((resizeConfig === null || resizeConfig === void 0 ? void 0 : resizeConfig.size.width) ?? 0, (resizeConfig === null || resizeConfig === void 0 ? void 0 : resizeConfig.size.height) ?? 0);
const measureContainer = () => {
'worklet';
const measuremet = (0, _reactNativeReanimated.measure)(containerRef);
if (measuremet !== null) {
containerSize.width.value = measuremet.width;
containerSize.height.value = measuremet.height;
position.x.value = measuremet.pageX;
position.y.value = measuremet.pageY;
}
};
const childrenSize = (0, _reactNativeReanimated.useDerivedValue)(() => {
return (0, _resizeToAspectRatio.resizeToAspectRatio)({
resizeConfig,
width: containerSize.width.value,
height: containerSize.height.value,
scale: scale.value
});
}, [resizeConfig, containerSize, scale]);
(0, _reactNativeReanimated.useDerivedValue)(() => {
const state = {
size: {
width: containerSize.width.value,
height: containerSize.height.value
},
position: {
x: position.x.value,
y: position.y.value
},
translateX: translate.x.value - childrenSize.value.deltaX,
translateY: translate.y.value - childrenSize.value.deltaY,
scale: scale.value
};
if (resizeConfig !== undefined) {
state.resize = {
width: childrenSize.value.width,
height: childrenSize.value.height
};
}
onUpdate === null || onUpdate === void 0 || onUpdate(state);
}, [containerSize, position, childrenSize, resizeConfig, translate, scale]);
const pinch = _reactNativeGestureHandler.Gesture.Pinch().withTestId('pinch').hitSlop(hitSlop).enabled(gesturesEnabled).onTouchesMove(e => {
if (e.numberOfTouches !== 2) return;
const one = e.allTouches[0];
const two = e.allTouches[1];
currentFocal.x.value = (one.absoluteX + two.absoluteX) / 2;
currentFocal.y.value = (one.absoluteY + two.absoluteY) / 2;
}).onStart(e => {
measureContainer();
onPinchStart && onPinchStart(e);
initialFocal.x.value = currentFocal.x.value;
initialFocal.y.value = currentFocal.y.value;
origin.x.value = e.focalX - containerSize.width.value / 2;
origin.y.value = e.focalY - containerSize.height.value / 2;
}).onUpdate(e => {
measureContainer();
const deltaX = currentFocal.x.value - initialFocal.x.value;
const deltaY = currentFocal.y.value - initialFocal.y.value;
const toX = -1 * (origin.x.value * e.scale - origin.x.value) + deltaX;
const toY = -1 * (origin.y.value * e.scale - origin.y.value) + deltaY;
translate.x.value = toX;
translate.y.value = toY;
scale.value = e.scale;
}).onEnd(e => {
onPinchEnd && (0, _reactNativeReanimated.runOnJS)(onPinchEnd)(e);
translate.x.value = (0, _reactNativeReanimated.withTiming)(0, timingConfig);
translate.y.value = (0, _reactNativeReanimated.withTiming)(0, timingConfig);
scale.value = (0, _reactNativeReanimated.withTiming)(1, timingConfig, _ => {
onGestureEnd && (0, _reactNativeReanimated.runOnJS)(onGestureEnd)();
});
});
if (scrollRef !== undefined) {
pinch.blocksExternalGesture(scrollRef);
}
const tap = _reactNativeGestureHandler.Gesture.Tap().withTestId('tap').enabled(gesturesEnabled).maxDuration(250).numberOfTaps(1).runOnJS(true).onEnd(e => onTap === null || onTap === void 0 ? void 0 : onTap(e));
const doubleTap = _reactNativeGestureHandler.Gesture.Tap().withTestId('doubleTap').enabled(gesturesEnabled).numberOfTaps(2).maxDuration(250).runOnJS(true).onEnd(e => onDoubleTap === null || onDoubleTap === void 0 ? void 0 : onDoubleTap(e));
const longPress = _reactNativeGestureHandler.Gesture.LongPress().withTestId('longPress').enabled(gesturesEnabled).minDuration(longPressDuration).runOnJS(true).onStart(e => onLongPress === null || onLongPress === void 0 ? void 0 : onLongPress(e));
const containerStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
width: resizeConfig === null || resizeConfig === void 0 ? void 0 : resizeConfig.size.width,
height: resizeConfig === null || resizeConfig === void 0 ? void 0 : resizeConfig.size.height,
justifyContent: 'center',
alignItems: 'center'
}), [resizeConfig]);
const childStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
const {
width,
height,
deltaX,
deltaY
} = childrenSize.value;
return {
width: width === 0 ? undefined : width,
height: height === 0 ? undefined : height,
transform: [{
translateX: translate.x.value - deltaX
}, {
translateY: translate.y.value - deltaY
}, {
scale: scale.value
}]
};
}, [childrenSize, translate, scale]);
const composedTapGesture = _reactNativeGestureHandler.Gesture.Exclusive(doubleTap, tap, longPress);
return /*#__PURE__*/_react.default.createElement(_reactNativeGestureHandler.GestureDetector, {
gesture: _reactNativeGestureHandler.Gesture.Race(pinch, composedTapGesture)
}, /*#__PURE__*/_react.default.createElement(_reactNativeReanimated.default.View, {
style: containerStyle,
ref: containerRef
}, /*#__PURE__*/_react.default.createElement(_reactNativeReanimated.default.View, {
style: childStyle
}, children)));
};
var _default = exports.default = (0, _withSnapbackValidation.default)(SnapbackZoom);
//# sourceMappingURL=SnapbackZoom.js.map
;