react-native-media-viewing
Version:
React Native modal component for viewing images and video as a sliding gallery
95 lines (94 loc) • 3.44 kB
JavaScript
import { Animated, PanResponder, } from "react-native";
export const createCache = (cacheSize) => ({
_storage: [],
get(key) {
const { value } = this._storage.find(({ key: storageKey }) => storageKey === key) || {};
return value;
},
set(key, value) {
if (this._storage.length >= cacheSize) {
this._storage.shift();
}
this._storage.push({ key, value });
},
});
export const splitArrayIntoBatches = (arr, batchSize) => arr.reduce((result, item) => {
const batch = result.pop() || [];
if (batch.length < batchSize) {
batch.push(item);
result.push(batch);
}
else {
result.push(batch, [item]);
}
return result;
}, []);
export const getImageTransform = (image, screen) => {
var _a, _b;
if (!((_a = image) === null || _a === void 0 ? void 0 : _a.width) || !((_b = image) === null || _b === void 0 ? void 0 : _b.height)) {
return [];
}
const wScale = screen.width / image.width;
const hScale = screen.height / image.height;
const scale = Math.min(wScale, hScale);
const { x, y } = getImageTranslate(image, screen);
return [{ x, y }, scale];
};
export const getImageStyles = (image, translate, scale) => {
var _a, _b;
if (!((_a = image) === null || _a === void 0 ? void 0 : _a.width) || !((_b = image) === null || _b === void 0 ? void 0 : _b.height)) {
return { width: 0, height: 0 };
}
const transform = translate.getTranslateTransform();
if (scale) {
transform.push({ scale }, { perspective: new Animated.Value(1000) });
}
return {
width: image.width,
height: image.height,
transform,
};
};
export const getImageTranslate = (image, screen) => {
const getTranslateForAxis = (axis) => {
const imageSize = axis === "x" ? image.width : image.height;
const screenSize = axis === "x" ? screen.width : screen.height;
return (screenSize - imageSize) / 2;
};
return {
x: getTranslateForAxis("x"),
y: getTranslateForAxis("y"),
};
};
export const getImageDimensionsByTranslate = (translate, screen) => ({
width: screen.width - translate.x * 2,
height: screen.height - translate.y * 2,
});
export const getImageTranslateForScale = (currentTranslate, targetScale, screen) => {
const { width, height } = getImageDimensionsByTranslate(currentTranslate, screen);
const targetImageDimensions = {
width: width * targetScale,
height: height * targetScale,
};
return getImageTranslate(targetImageDimensions, screen);
};
export const createPanResponder = ({ onGrant, onStart, onMove, onRelease, onTerminate, }) => PanResponder.create({
onStartShouldSetPanResponder: () => true,
onStartShouldSetPanResponderCapture: () => true,
onMoveShouldSetPanResponder: () => true,
onMoveShouldSetPanResponderCapture: () => true,
onPanResponderGrant: onGrant,
onPanResponderStart: onStart,
onPanResponderMove: onMove,
onPanResponderRelease: onRelease,
onPanResponderTerminate: onTerminate,
onPanResponderTerminationRequest: () => false,
onShouldBlockNativeResponder: () => false,
});
export const getDistanceBetweenTouches = (touches) => {
const [a, b] = touches;
if (a == null || b == null) {
return 0;
}
return Math.sqrt(Math.pow(a.pageX - b.pageX, 2) + Math.pow(a.pageY - b.pageY, 2));
};