Ущипните, чтобы увеличить масштаб таблицы с возможностью прокруткиAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Ущипните, чтобы увеличить масштаб таблицы с возможностью прокрутки

Сообщение Anonymous »

При выполнении жеста масштабирования точка фокуса (точка между двумя пальцами) должна оставаться фиксированной.
Но в моем случае это не так.
Точка фокуса начинается прямо на квадрате, но при увеличении масштаба квадрат перемещается от этой точки, а не остается под ней.
По сути, масштаб не остается в центре фокуса, как ожидалось.
вот код для обработки жеста сжатия:
const [refreshing, setRefreshing] = useState(false);
const [contentSize, setContentSize] = useState({ width: 0, height: 0 });
const [scaleJS, setScaleJS] = useState(1);
const verticalScrollRef = useRef(null);
const horizontalScrollRef = useRef(null);
const doubleTapRef = useRef(null);
const translateX = useSharedValue(0);
const translateY = useSharedValue(0);
const scale = useSharedValue(1);
const savedScale = useSharedValue(1);
const lastOffset = useSharedValue({ x: 0, y: 0 });
const panRef = useRef(null);
const pinchRef = useRef(null);
const { width, height } = useWindowDimensions();
const [viewport, setViewport] = useState({ width, height });

const MIN_ZOOM = 0.1;
const MAX_ZOOM = 3.0;

const onPinchGestureEvent = (event: any) => {
"worklet";
const { scale: gestureScale, focalX, focalY } = event.nativeEvent;

const nextScale = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, savedScale.value * gestureScale));

const pinchRatio = nextScale / scale.value;

let nextX = translateX.value + (focalX - translateX.value) * (1 - pinchRatio);
let nextY = translateY.value + (focalY - translateY.value) * (1 - pinchRatio);

const scaledW = contentSize.width * nextScale;
const scaledH = contentSize.height * nextScale;

const minX = viewport.width < scaledW ? viewport.width - scaledW : 0;
const minY = viewport.height < scaledH ? viewport.height - scaledH : 0;

nextX = Math.min(0, Math.max(nextX, minX));
nextY = Math.min(0, Math.max(nextY, minY));

translateX.value = nextX;
translateY.value = nextY;
scale.value = nextScale;
};

const onPinchEnd = () => {
"worklet";
savedScale.value = scale.value;
lastOffset.value = { x: translateX.value, y: translateY.value };

if (scale.value {
cancelAnimation(scale);

scale.value = withTiming(1, { duration: 180 });
savedScale.value = 1;

translateX.value = withTiming(0, { duration: 180 });
translateY.value = withTiming(0, { duration: 180 });

setScaleJS(1);

verticalScrollRef.current?.scrollTo({ y: 0, animated: false });
horizontalScrollRef.current?.scrollTo({ x: 0, animated: false });

}, []);

const onViewportLayout = (event: any) => {
const { width, height } = event.nativeEvent.layout;
setViewport({ width, height });
};

const onContentLayout = (event: any) => {
const { width, height } = event.nativeEvent.layout;
setContentSize({ width, height });
};

const onPanGestureEvent = (event: any) => {
"worklet";

const scaledW = contentSize.width * scale.value;
const scaledH = contentSize.height * scale.value;

// Limits: Content edge vs Viewport edge
const minX = viewport.width < scaledW ? viewport.width - scaledW : 0;
const minY = viewport.height < scaledH ? viewport.height - scaledH : 0;

let nextX = lastOffset.value.x + event.nativeEvent.translationX;
let nextY = lastOffset.value.y + event.nativeEvent.translationY;

// CLAMP: Never let the user scroll past the content edges
translateX.value = Math.min(0, Math.max(nextX, minX));
translateY.value = Math.min(0, Math.max(nextY, minY));
};

const onPanEnd = () => {
"worklet";
lastOffset.value = { x: translateX.value, y: translateY.value };
};

return (



{!!error && (

Couldn’t load matches
{String(error)}
onRefresh()}>
Retry


)}

{status === "loading" && page === 1 ? (



) : null}
setViewport(e.nativeEvent.layout)}>


{
if (e.nativeEvent.state === State.END) {
resetZoom();
}
}}
>









{drawPaths.map((p, i) => (

))}


{bracket.rounds.map((r) => {
const colH = layout.colHeights[r.id] ?? layout.surfaceH;
const list = bracket.matchesByRound[r.id] || [];
return (

{r.name}

{list.map((m) => {
const rect = layout.pos[idOf(m)];
const top = rect ? rect.y - UI.ROUND_TITLE_H : 0;
return (



);
})}
{!list.length && No matches}


);
})}
{showMoreCard ? (

More

{status === "loading" ? "Loading..." : "Load More"}


) : null}









);
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... able-table
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»