Panzoom: Масштабирование смещает изображение от центра экрана.

Созданный на 21 сент. 2020  ·  19Комментарии  ·  Источник: timmywil/panzoom

Опишите ошибку

По какой-то причине при использовании моего приложения Panzoom на мобильном устройстве (любом устройстве) при попытке масштабирования изображение перемещается в правый угол при увеличении и в левый верхний угол при уменьшении вместо увеличения на месте. Иногда, когда вы только запускаете приложение, уменьшение масштаба работает правильно перед перемещением изображения, а затем проблема возвращается.

Увеличение и уменьшение масштаба с помощью колеса прокрутки работает так, как должно, это не работает только с масштабированием.

Ваша среда

  • Последняя версия (установлена ​​сегодня)
  • Браузер Vivaldi, браузер Kiwi, Chrome, Firefox, все последние версии.

Ожидаемое поведение

Увеличенное изображение должно оставаться по центру там, где пользователь увеличивает/уменьшает масштаб.

Фактическое поведение

Увеличенное изображение перемещается, и при увеличении центрируется нижняя правая часть изображения на экране, а при уменьшении масштаба центрируется верхний левый угол.

Самый полезный комментарий

Заменить функцию перемещения на panzoom.ts:426

функция перемещения (событие: PointerEvent) {
если (
!isПанорамирование ||
origX === не определено ||
origY === не определено ||
startClientX === не определено ||
startClientY === не определено
) {
вернуть
}
addPointer (указатели, событие)
постоянный текущий = getMiddle (указатели)
если (указатели.длина > 1) {
// Используем расстояние между первыми двумя указателями
// для определения текущего масштаба
// предотвращение проблемы с масштабированием на мобильных устройствах
если (начальное расстояние === 0) {
startDistance = getDistance (указатели);
}
const diff = getDistance(указатели) - startDistance
const toScale = constrainScale((diff * options.step) / 80 + startScale).scale
zoomToPoint (в масштабе, текущий)
} еще {
// добавлено еще условие для предотвращения ошибки фокуса мобильного зума
Сковорода(
origX+(current.clientX - startClientX)/масштаб,
origY + (current.clientY - startClientY) / масштаб,
{
анимация: ложь
}
);
}
}

Все 19 Комментарий

Спасибо за открытие вопроса. Я попробовал демо на iOS и Android и не смог воспроизвести. Вы перечислили настольные браузеры, но масштабирование в основном предназначено для мобильных устройств (хотя на некоторых устройствах есть и мышь, и сенсорный экран). Может быть полезно знать, какое устройство вы используете, хотя я, скорее всего, не смогу протестировать его.

Я мало что могу сделать, не имея возможности воспроизвести проблему. Если вы копнете глубже и обнаружите, что изменение кода в Panzoom исправляет проблему (или что проблема воспроизводится в другом тестовом примере, кроме демо), пожалуйста, прокомментируйте здесь, и я рассмотрю исправление.

Привет, мистер Уиллисон;

Спасибо за ваш ответ. Я использовал как десктопную, так и мобильную версии
сказали браузеры. Я использовал Redmi Note 8T и Galaxy 8, чтобы проверить это.

Чтобы увидеть эту проблему, может быть, вы взглянете на демо, которое я разрабатываю?
Просто введите имя (ничего не сохраняется, это просто детская игра) и нажмите
на кнопку «Исследовать свет»; вы будете перенаправлены на Panzoomed
изображение. Как вы увидите, масштабирование колесиком мыши работает нормально, но масштабирование щипком (и
на самом деле кнопки panzoom.zoomIn() и panzoom.zoomOut() также перемещают
изображение.

http://bake250.isdeveloping.com/objectiuexplora/solsticidelspirineus/

Я очень благодарен за вашу помощь, и, пожалуйста, извините за неудобства.

С наилучшими пожеланиями;

Хорхе Санчес Бланко

Эль лун., 21 сент. 2020 в 19:45, Тимми Уиллисон (<
уведомления@github.com>) запись:

Спасибо за открытие вопроса. я попробовал демо
https://timmywil.com/panzoom/demo на iOS и Android и не смог
воспроизводить. Вы перечислили настольные браузеры, но масштабирование щипком в основном предназначено для
мобильный (хотя на некоторых устройствах есть и мышь, и сенсорный экран). Это может
быть полезным, чтобы узнать, какое устройство вы используете, даже если я, вероятно,
нет возможности протестировать на нем.

Я мало что могу сделать, не имея возможности воспроизвести проблему. Если
вы копаете глубже и обнаруживаете, что изменение кода в Panzoom исправляет это (или что
другой тестовый пример, кроме того, что демо воспроизводит проблему), пожалуйста
прокомментируйте здесь, и я рассмотрю патч.


Вы получаете это, потому что вы создали тему.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/timmywil/panzoom/issues/512#issuecomment-696267620 ,
или отписаться
https://github.com/notifications/unsubscribe-auth/AOF4EAOK6YQVAHINOAQ3JZTSG6GMRANCNFSM4RUT4P7A
.

У меня такая же проблема. Похоже, что точка фокусировки не рассчитана должным образом и находится полностью внизу.

@jsblanco Понятно . Panzoom полагается на transform-origin: 50% 50% , который центрирует анимацию в центре области просмотра, а не в центре изображения, что в этом случае было бы ниже. Он перемещает изображение из-за настройки contain: outside , чтобы изображение не опускалось слишком далеко. Я думаю, что это можно исправить, вызвав zoomToPoint или используя вместо этого zoom с опцией focal и найдя точку в окне просмотра, которая на самом деле является центром изображения. Имеет ли это смысл?

Возможно, я мог бы сделать что-то подобное по умолчанию, когда установлено значение contain: outside .

@rmatec Вы также используете contain: outside ?

Я не использую опцию содержания. В моем случае кажется, что фокус находится внизу по центру. Защемление внутрь или наружу делается относительно этой точки.

@rmatec Я думаю, что в игре должен быть какой-то вариант, так как я не вижу такого поведения в демоверсиях. Есть ли другой вариант, который вы устанавливаете?

Я использую следующее для инициализации Panzoom.

const panzoomConfig = { minScale: 1, maxScale: 2, step: 0.5, duration: 200 };

Он прекрасно работает на десктопе, но почему-то не работает на мобильных устройствах.

Хорошо, ваш случай звучит так, как будто он может быть другим. Не могли бы вы воспроизвести в https://jsbin.com или https://codepen.io и сделать новый тикет? Вот шаблон, который можно клонировать https://jsbin.com/dibofogini/1/edit?html , js, output.

Сделаю. Спасибо.

По какой-то причине при использовании опции фокуса изображение появляется рядом с
внизу справа, и дальнейшее увеличение или уменьшение масштаба невозможно.
Может я что-то не так делаю? Должен ли я передавать какие-либо конкретные параметры
в panzoom.zoomIn() и .zoomOut(), чтобы указать точку фокусировки, или просто
должно быть достаточно включения его в первоначальное объявление panzoom?

Что бы это ни стоило, я пробовал следующие методы получения фокуса.
точка. Я также попытался ввести необработанные числа.

clientX: window.innerWidth /2,
clientY: window.innerHeight/2

clientX: document.documentElement.clientWidth/2,
clientY: document.documentElement.clientHeight/2

Удаление содержимого: снаружи просто отображает черное изображение.

Эль-Мар, 22 сент. 2020 в 15:59, Тимми Уиллисон (<
уведомления@github.com>) запись:

@jsblanco https://github.com/jsblanco Понятно. Panzoom полагается на преобразование-происхождение:
50% 50%, что центрирует анимацию в центре области просмотра, а не
чем по центру изображения, который в этом случае был бы ниже. Это
перемещает изображение из-за настройки «содержит: снаружи», чтобы предотвратить
изображение от захода слишком далеко вниз. Я думаю, это можно исправить, позвонив
zoomToPoint или используя зум с опцией фокуса вместо этого и находя
точка в окне просмотра, которая фактически является центром изображения. Делает
Это имеет смысл?

Возможно, я мог бы сделать что-то подобное по умолчанию, когда содержал: снаружи
установлен.

@rmatec https://github.com/rmatec Вы также используете contains: снаружи?


Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/timmywil/panzoom/issues/512#issuecomment-696740708 ,
или отписаться
https://github.com/notifications/unsubscribe-auth/AOF4EANBQXE5TDJOZNTBN6LSHCUVXANCNFSM4RUT4P7A
.

@jsblanco Извините, это сложнее. Это можно сделать, найдя центр изображения и переместив его в точку родительского окна панорамного масштабирования. Затем вы передадите это как параметр фокуса, и он должен рассчитываться каждый раз, когда вы вызываете масштабирование. Тем не менее, позвольте мне посмотреть, смогу ли я разработать пример для вас. Это исправит zoomIn / zoomOut .

Тем не менее, это не изменит поведение масштабирования. Возможно, это правильно, так как масштабирование определенных точек натыкается на contain: outside . Я не уверен, что это исправление, за исключением, возможно, запрета масштабирования, если изображение должно двигаться, чтобы оно правильно отображалось в окне просмотра.

Хорошо, ваш случай звучит так, как будто он может быть другим. Не могли бы вы воспроизвести в https://jsbin.com или https://codepen.io и сделать новый тикет? Вот шаблон, который можно клонировать https://jsbin.com/dibofogini/1/edit?html , js, output.

Я создал https://github.com/timmywil/panzoom/issues/513 для своего конкретного случая. Есть ссылка на JSBin, которая показывает проблему.

Я могу воспроизвести эту проблему, если оставлю «animate: true» включенным.
Эта проблема не появляется в «animate: false» — я клонировал ваш шаблон @timmywil , чтобы воспроизвести эту проблему:

https://jsbin.com/pemoveyeri/1/edit?

(Я реализовал прослушиватель событий колеса для прямого масштабирования - если вы прокручиваете достаточно быстро, произойдет смещение положения.)

Хорошо, я переместил свою проблему в # 515, потому что проблема та же, но с другой конфигурацией.

Привет;

Извините, что долго не отвечал. Я не думаю, что это связано с contains="outside"; Я только что удалил его, и он по-прежнему вел себя так же, хотя и не так интенсивно. Однако div panzoom и изображение имеют заданный размер, не зависящий от размера улицы; это может быть частью проблемы?

Спасибо

@jsblanco Исправление должно быть таким же.

Привет, я собирался открыть новую тему о масштабировании колеса, удаляющемся от центра, но просмотрел этот и подумал, что он достаточно связан. Ниже приведены мои выводы и обходной путь. Обратите внимание, что я тестировал только в браузерах на MacBook с использованием трекпада.

Я заметил, что для демонстрации масштабирования фокусной точки центр плавает в верхнем левом углу при масштабировании в Safari, Firefox. Я получаю такое же поведение даже в Chrome, но только при открытом веб-инспекторе.

Итак, я начал изучать это, и я подозреваю, что событие колесика мыши срабатывает слишком часто, и вещи не обновляются должным образом из-за асинхронной природы Panzoom . Я подумал, что если я попытаюсь уменьшить частоту масштабирования, это может помочь, и, конечно же, это «работает». Вы можете увидеть это в действии здесь: https://jsbin.com/joliduwulo/1/edit?html,js,output .

Предостережение в том, что масштабирование будет выглядеть менее плавным. В этом примере я ограничиваю его одним максимальным масштабированием каждые 20 мс, но когда я тестировал большие SVG, особенно в Firefox, мне нужно было установить это значение около 50 мс, чтобы не потерять фокус.

@timmywil, пожалуйста, дайте мне знать, если вы хотите, чтобы я все равно открыл новую проблему. Это похоже на взлом, но это решает проблему для меня. Если вы считаете, что решение стоит изучить, я был бы рад помочь внести свой вклад.

+1 за возможность центрироваться на элементе панорамы, а не на окне просмотра

Заменить функцию перемещения на panzoom.ts:426

функция перемещения (событие: PointerEvent) {
если (
!isПанорамирование ||
origX === не определено ||
origY === не определено ||
startClientX === не определено ||
startClientY === не определено
) {
вернуть
}
addPointer (указатели, событие)
постоянный текущий = getMiddle (указатели)
если (указатели.длина > 1) {
// Используем расстояние между первыми двумя указателями
// для определения текущего масштаба
// предотвращение проблемы с масштабированием на мобильных устройствах
если (начальное расстояние === 0) {
startDistance = getDistance (указатели);
}
const diff = getDistance(указатели) - startDistance
const toScale = constrainScale((diff * options.step) / 80 + startScale).scale
zoomToPoint (в масштабе, текущий)
} еще {
// добавлено еще условие для предотвращения ошибки фокуса мобильного зума
Сковорода(
origX+(current.clientX - startClientX)/масштаб,
origY + (current.clientY - startClientY) / масштаб,
{
анимация: ложь
}
);
}
}

Была ли эта страница полезной?
0 / 5 - 0 рейтинги