Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F33300960
D14305.1768773402.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D14305.1768773402.diff
View Options
diff --git a/native/components/full-screen-view-modal.react.js b/native/components/full-screen-view-modal.react.js
--- a/native/components/full-screen-view-modal.react.js
+++ b/native/components/full-screen-view-modal.react.js
@@ -56,6 +56,7 @@
gestureJustStarted,
gestureJustEnded,
runTiming,
+ clampV2,
} from '../utils/animation-utils.js';
const {
@@ -90,34 +91,6 @@
decay,
} = Animated;
-function scaleDelta(value: Node, gestureActive: Node): Node {
- const diffThisFrame = new Value(1);
- const prevValue = new Value(1);
- return cond(
- gestureActive,
- [
- set(diffThisFrame, divide(value, prevValue)),
- set(prevValue, value),
- diffThisFrame,
- ],
- set(prevValue, 1),
- );
-}
-
-function panDelta(value: Node, gestureActive: Node): Node {
- const diffThisFrame = new Value(0);
- const prevValue = new Value(0);
- return cond(
- gestureActive,
- [
- set(diffThisFrame, sub(value, prevValue)),
- set(prevValue, value),
- diffThisFrame,
- ],
- set(prevValue, 0),
- );
-}
-
function runDecay(
clock: Clock,
velocity: Node,
@@ -380,17 +353,6 @@
);
const updates = [
- this.doubleTapUpdate(
- doubleTapState,
- doubleTapX,
- doubleTapY,
- roundedCurScale,
- zoomClock,
- gestureActive,
- curScale,
- curX,
- curY,
- ),
this.backdropOpacityUpdate(
panJustEnded,
pinchActive,
@@ -492,79 +454,6 @@
return max(vertPop, 0);
}
- doubleTapUpdate(
- // Inputs
- doubleTapState: Node,
- doubleTapX: Node,
- doubleTapY: Node,
- roundedCurScale: Node,
- zoomClock: Clock,
- gestureActive: Node,
- // Outputs
- curScale: Value,
- curX: Value,
- curY: Value,
- ): Node {
- const zoomClockRunning = clockRunning(zoomClock);
- const zoomActive = and(not(gestureActive), zoomClockRunning);
- const targetScale = cond(greaterThan(roundedCurScale, 1), 1, 3);
-
- const tapXDiff = sub(doubleTapX, this.centerX, curX);
- const tapYDiff = sub(doubleTapY, this.centerY, curY);
- const tapXPercent = divide(tapXDiff, this.imageWidth, curScale);
- const tapYPercent = divide(tapYDiff, this.imageHeight, curScale);
-
- const horizPanSpace = this.horizontalPanSpace(targetScale);
- const vertPanSpace = this.verticalPanSpace(targetScale);
- const horizPanPercent = divide(horizPanSpace, this.imageWidth, targetScale);
- const vertPanPercent = divide(vertPanSpace, this.imageHeight, targetScale);
-
- const tapXPercentClamped = clamp(
- tapXPercent,
- multiply(-1, horizPanPercent),
- horizPanPercent,
- );
- const tapYPercentClamped = clamp(
- tapYPercent,
- multiply(-1, vertPanPercent),
- vertPanPercent,
- );
- const targetX = multiply(tapXPercentClamped, this.imageWidth, targetScale);
- const targetY = multiply(tapYPercentClamped, this.imageHeight, targetScale);
-
- const targetRelativeScale = divide(targetScale, curScale);
- const targetRelativeX = multiply(-1, add(targetX, curX));
- const targetRelativeY = multiply(-1, add(targetY, curY));
-
- const zoomScale = runTiming(zoomClock, 1, targetRelativeScale);
- const zoomX = runTiming(zoomClock, 0, targetRelativeX, false);
- const zoomY = runTiming(zoomClock, 0, targetRelativeY, false);
-
- const deltaScale = scaleDelta(zoomScale, zoomActive);
- const deltaX = panDelta(zoomX, zoomActive);
- const deltaY = panDelta(zoomY, zoomActive);
-
- const fingerJustReleased = and(
- gestureJustEnded(doubleTapState),
- // TODO: migrate this in the next diffs
- // this.outsideButtons(doubleTapX, doubleTapY),
- 1,
- );
-
- return cond(
- [fingerJustReleased, deltaX, deltaY, deltaScale, gestureActive],
- stopClock(zoomClock),
- cond(or(zoomClockRunning, fingerJustReleased), [
- zoomX,
- zoomY,
- zoomScale,
- set(curX, add(curX, deltaX)),
- set(curY, add(curY, deltaY)),
- set(curScale, multiply(curScale, deltaScale)),
- ]),
- );
- }
-
backdropOpacityUpdate(
// Inputs
panJustEnded: Node,
@@ -1103,6 +992,32 @@
const centerX = useSharedValue(dimensions.width / 2);
const centerY = useSharedValue(dimensions.safeAreaHeight / 2);
+ const frameWidth = useSharedValue(dimensions.width);
+ const frameHeight = useSharedValue(dimensions.safeAreaHeight);
+ const imageWidth = useSharedValue(props.contentDimensions.width);
+ const imageHeight = useSharedValue(props.contentDimensions.height);
+
+ // How much space do we have to pan the image horizontally?
+ const getHorizontalPanSpace = React.useCallback(
+ (scale: number): number => {
+ 'worklet';
+ const apparentWidth = imageWidth.value * scale;
+ const horizPop = (apparentWidth - frameWidth.value) / 2;
+ return Math.max(horizPop, 0);
+ },
+ [frameWidth, imageWidth],
+ );
+
+ // How much space do we have to pan the image vertically?
+ const getVerticalPanSpace = React.useCallback(
+ (scale: number): number => {
+ 'worklet';
+ const apparentHeight = imageHeight.value * scale;
+ const vertPop = (apparentHeight - frameHeight.value) / 2;
+ return Math.max(vertPop, 0);
+ },
+ [frameHeight, imageHeight],
+ );
const lastPinchScale = useSharedValue(1);
@@ -1245,6 +1160,57 @@
[outsideButtons, toggleActionLinks, toggleCloseButton, roundedCurScale],
);
+ const doubleTapUpdate = React.useCallback(
+ ({ x, y }: TapGestureEvent) => {
+ 'worklet';
+ if (!outsideButtons(x, y)) {
+ return;
+ }
+ const targetScale = roundedCurScale.value > 1 ? 1 : 3;
+
+ const tapXDiff = x - centerX.value - curX.value;
+ const tapYDiff = y - centerY.value - curY.value;
+ const tapXPercent = tapXDiff / imageWidth.value / curScale.value;
+ const tapYPercent = tapYDiff / imageHeight.value / curScale.value;
+
+ const horizPanSpace = getHorizontalPanSpace(targetScale);
+ const vertPanSpace = getVerticalPanSpace(targetScale);
+ const horizPanPercent = horizPanSpace / imageWidth.value / targetScale;
+ const vertPanPercent = vertPanSpace / imageHeight.value / targetScale;
+
+ const tapXPercentClamped = clampV2(
+ tapXPercent,
+ -horizPanPercent,
+ horizPanPercent,
+ );
+ const tapYPercentClamped = clampV2(
+ tapYPercent,
+ -vertPanPercent,
+ vertPanPercent,
+ );
+
+ const targetX = tapXPercentClamped * imageWidth.value * targetScale;
+ const targetY = tapYPercentClamped * imageHeight.value * targetScale;
+
+ curScale.value = withTiming(targetScale, defaultTimingConfig);
+ curX.value = withTiming(targetX, defaultTimingConfig);
+ curY.value = withTiming(targetY, defaultTimingConfig);
+ },
+ [
+ centerX,
+ centerY,
+ curScale,
+ curX,
+ curY,
+ getHorizontalPanSpace,
+ imageHeight,
+ imageWidth,
+ outsideButtons,
+ roundedCurScale,
+ getVerticalPanSpace,
+ ],
+ );
+
const gesture = React.useMemo(() => {
const pinchGesture = Gesture.Pinch()
.onStart(pinchStart)
@@ -1254,7 +1220,9 @@
.onStart(panStart)
.onUpdate(panUpdate)
.onEnd(panEnd);
- const doubleTapGesture = Gesture.Tap().numberOfTaps(2);
+ const doubleTapGesture = Gesture.Tap()
+ .numberOfTaps(2)
+ .onEnd(doubleTapUpdate);
const singleTapGesture = Gesture.Tap()
.numberOfTaps(1)
.onEnd(singleTapUpdate);
@@ -1264,7 +1232,15 @@
doubleTapGesture,
singleTapGesture,
);
- }, [panEnd, panStart, panUpdate, pinchStart, pinchUpdate, singleTapUpdate]);
+ }, [
+ doubleTapUpdate,
+ panEnd,
+ panStart,
+ panUpdate,
+ pinchStart,
+ pinchUpdate,
+ singleTapUpdate,
+ ]);
return (
<FullScreenViewModal
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 18, 9:56 PM (2 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5953178
Default Alt Text
D14305.1768773402.diff (7 KB)
Attached To
Mode
D14305: [native] Migrate double tap gesture handling in FullScreenViewModal
Attached
Detach File
Event Timeline
Log In to Comment