При выполнении жеста масштабирования точка фокуса (точка между двумя пальцами) должна оставаться фиксированной.
Но в моем случае это не так.
Точка фокуса начинается прямо на квадрате, но при увеличении масштаба квадрат перемещается от этой точки, а не остается под ней.
По сути, масштаб не остается в центре фокуса, как ожидалось.
вот код для обработки жеста сжатия:
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
Ущипните, чтобы увеличить масштаб таблицы с возможностью прокрутки ⇐ Android
Форум для тех, кто программирует под Android
-
Anonymous
1769604963
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}
);
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79877935/pinch-to-zoom-in-for-scrollable-table[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия