Fix gallery view
This commit is contained in:
@@ -10,7 +10,9 @@ import {
|
|||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import Animated, {
|
import Animated, {
|
||||||
|
runOnJS,
|
||||||
useAnimatedStyle,
|
useAnimatedStyle,
|
||||||
|
useAnimatedReaction,
|
||||||
useDerivedValue,
|
useDerivedValue,
|
||||||
useSharedValue,
|
useSharedValue,
|
||||||
} from 'react-native-reanimated'
|
} from 'react-native-reanimated'
|
||||||
@@ -38,7 +40,7 @@ type Props = {
|
|||||||
doubleTapToZoomEnabled?: boolean
|
doubleTapToZoomEnabled?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type Matrix3 = readonly [
|
type Matrix3 = [
|
||||||
number,
|
number,
|
||||||
number,
|
number,
|
||||||
number,
|
number,
|
||||||
@@ -106,6 +108,14 @@ function prependPinch(t, scale, origin, translation) {
|
|||||||
prependTranslate(t, -origin.x, -origin.y);
|
prependTranslate(t, -origin.x, -origin.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function applyRounding(t) {
|
||||||
|
'worklet'
|
||||||
|
t[2] = Math.round(t[2])
|
||||||
|
t[5] = Math.round(t[5])
|
||||||
|
t[0] = Math.round(t[0] * 200) / 200;
|
||||||
|
t[4] = Math.round(t[0] * 200) / 200;
|
||||||
|
}
|
||||||
|
|
||||||
function toStyle(t) {
|
function toStyle(t) {
|
||||||
"worklet";
|
"worklet";
|
||||||
const [translateX, translateY, scale] = readTransform(t)
|
const [translateX, translateY, scale] = readTransform(t)
|
||||||
@@ -154,6 +164,7 @@ const ImageItem = ({
|
|||||||
swipeToCloseEnabled = true,
|
swipeToCloseEnabled = true,
|
||||||
doubleTapToZoomEnabled = true,
|
doubleTapToZoomEnabled = true,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
|
const [isScaled, setIsScaled] = useState(false)
|
||||||
const imageDimensions = useImageDimensions(imageSrc)
|
const imageDimensions = useImageDimensions(imageSrc)
|
||||||
const committedTransform = useSharedValue(initialTransform)
|
const committedTransform = useSharedValue(initialTransform)
|
||||||
const pinchOrigin = useSharedValue({ x: 0, y: 0 })
|
const pinchOrigin = useSharedValue({ x: 0, y: 0 })
|
||||||
@@ -161,6 +172,24 @@ const ImageItem = ({
|
|||||||
const pinchTranslation = useSharedValue({ x: 0, y: 0 })
|
const pinchTranslation = useSharedValue({ x: 0, y: 0 })
|
||||||
const panTranslation = useSharedValue({ x: 0, y: 0 })
|
const panTranslation = useSharedValue({ x: 0, y: 0 })
|
||||||
|
|
||||||
|
useAnimatedReaction(
|
||||||
|
() => {
|
||||||
|
if (pinchScale.value !== 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const [,,scale] = readTransform(committedTransform.value)
|
||||||
|
if (scale !== 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
(isScaledNow, wasScaledBefore) => {
|
||||||
|
if (isScaledNow !== wasScaledBefore) {
|
||||||
|
runOnJS(setIsScaled)(isScaledNow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const animatedStyle = useAnimatedStyle(() => {
|
const animatedStyle = useAnimatedStyle(() => {
|
||||||
let t = createTransform();
|
let t = createTransform();
|
||||||
prependPan(t, panTranslation.value);
|
prependPan(t, panTranslation.value);
|
||||||
@@ -210,6 +239,7 @@ const ImageItem = ({
|
|||||||
let t = createTransform();
|
let t = createTransform();
|
||||||
prependPinch(t, pinchScale.value, pinchOrigin.value, pinchTranslation.value)
|
prependPinch(t, pinchScale.value, pinchOrigin.value, pinchTranslation.value)
|
||||||
prependTransform(t, committedTransform.value);
|
prependTransform(t, committedTransform.value);
|
||||||
|
applyRounding(t)
|
||||||
committedTransform.value = t
|
committedTransform.value = t
|
||||||
pinchScale.value = 1;
|
pinchScale.value = 1;
|
||||||
pinchOrigin.value = { x: 0, y: 0 };
|
pinchOrigin.value = { x: 0, y: 0 };
|
||||||
@@ -218,6 +248,7 @@ const ImageItem = ({
|
|||||||
|
|
||||||
const pan = Gesture.Pan()
|
const pan = Gesture.Pan()
|
||||||
.averageTouches(true)
|
.averageTouches(true)
|
||||||
|
.enabled(isScaled)
|
||||||
.onChange((e) => {
|
.onChange((e) => {
|
||||||
if (!imageDimensions) {
|
if (!imageDimensions) {
|
||||||
return;
|
return;
|
||||||
@@ -232,6 +263,7 @@ const ImageItem = ({
|
|||||||
let t = createTransform();
|
let t = createTransform();
|
||||||
prependPan(t, panTranslation.value)
|
prependPan(t, panTranslation.value)
|
||||||
prependTransform(t, committedTransform.value);
|
prependTransform(t, committedTransform.value);
|
||||||
|
applyRounding(t)
|
||||||
committedTransform.value = t
|
committedTransform.value = t
|
||||||
panTranslation.value = { x: 0, y: 0 };
|
panTranslation.value = { x: 0, y: 0 };
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -129,16 +129,41 @@ function ImageViewing({
|
|||||||
<ImageDefaultHeader onRequestClose={onRequestCloseEnhanced} />
|
<ImageDefaultHeader onRequestClose={onRequestCloseEnhanced} />
|
||||||
)}
|
)}
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
{/* TODO: show gallery again */}
|
<VirtualizedList
|
||||||
|
ref={imageList}
|
||||||
|
data={images}
|
||||||
|
horizontal
|
||||||
|
pagingEnabled
|
||||||
|
showsHorizontalScrollIndicator={false}
|
||||||
|
showsVerticalScrollIndicator={false}
|
||||||
|
getItem={(_, index) => images[index]}
|
||||||
|
getItemCount={() => images.length}
|
||||||
|
getItemLayout={(_, index) => ({
|
||||||
|
length: SCREEN_WIDTH,
|
||||||
|
offset: SCREEN_WIDTH * index,
|
||||||
|
index,
|
||||||
|
})}
|
||||||
|
renderItem={({item: imageSrc}) => (
|
||||||
<ImageItem
|
<ImageItem
|
||||||
onZoom={onZoom}
|
onZoom={onZoom}
|
||||||
imageSrc={images[0]}
|
imageSrc={imageSrc}
|
||||||
onRequestClose={onRequestCloseEnhanced}
|
onRequestClose={onRequestCloseEnhanced}
|
||||||
onLongPress={onLongPress}
|
onLongPress={onLongPress}
|
||||||
delayLongPress={delayLongPress}
|
delayLongPress={delayLongPress}
|
||||||
swipeToCloseEnabled={swipeToCloseEnabled}
|
swipeToCloseEnabled={swipeToCloseEnabled}
|
||||||
doubleTapToZoomEnabled={doubleTapToZoomEnabled}
|
doubleTapToZoomEnabled={doubleTapToZoomEnabled}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
onMomentumScrollEnd={onScroll}
|
||||||
|
//@ts-ignore
|
||||||
|
keyExtractor={(imageSrc, index) =>
|
||||||
|
keyExtractor
|
||||||
|
? keyExtractor(imageSrc, index)
|
||||||
|
: typeof imageSrc === 'number'
|
||||||
|
? `${imageSrc}`
|
||||||
|
: imageSrc.uri
|
||||||
|
}
|
||||||
|
/>
|
||||||
{typeof FooterComponent !== 'undefined' && (
|
{typeof FooterComponent !== 'undefined' && (
|
||||||
<Animated.View style={[styles.footer, {transform: footerTransform}]}>
|
<Animated.View style={[styles.footer, {transform: footerTransform}]}>
|
||||||
{React.createElement(FooterComponent, {
|
{React.createElement(FooterComponent, {
|
||||||
|
|||||||
Reference in New Issue
Block a user