Panzoom: Le zoom par pincement éloigne l'image du centre de l'écran

Créé le 21 sept. 2020  ·  19Commentaires  ·  Source: timmywil/panzoom

Décrivez le bogue

Pour une raison quelconque, lors de l'utilisation de mon application Panzoom sur mobile (n'importe quel appareil), lorsque vous essayez de zoomer par pincement, l'image se déplace vers le coin droit lors d'un zoom avant et vers le haut à gauche lors d'un zoom arrière, au lieu de zoomer sur place. Parfois, lors du démarrage de l'application, le zoom arrière fonctionne correctement avant de déplacer l'image, puis le problème revient.

Le zoom avant et arrière avec la molette de défilement fonctionne comme il se doit, c'est seulement le zoom par pincement qui ne fonctionne pas.

Votre environnement

  • Dernière version (installée aujourd'hui)
  • Navigateur Vivaldi, navigateur Kiwi, Chrome, Firefox, toutes les dernières versions.

Comportement prévisible

L'image agrandie doit rester centrée là où l'utilisateur effectue un zoom avant/arrière.

Comportement réel

L'image agrandie se déplace et le zoom avant centre le bas à droite de l'image sur l'écran, tandis que le zoom arrière centre le haut à gauche.

Commentaire le plus utile

Remplacer la fonction de déplacement sur panzoom.ts:426

fonction déplacer(événement : PointerEvent) {
si (
!isPanning ||
origX === non défini ||
origY === non défini ||
startClientX === non défini ||
startClientY === non défini
) {
retourner
}
addPointer(pointeurs, événement)
const courant = getMiddle(pointeurs)
si (pointeurs.longueur > 1) {
// Utilise la distance entre les 2 premiers pointeurs
// pour déterminer l'échelle courante
// empêche le problème de zoom sur mobile
si (startDistance === 0) {
startDistance = getDistance(pointeurs);
}
const diff = getDistance(pointeurs) - startDistance
const toScale = constrainScale((diff * options.step) / 80 + startScale).scale
zoomToPoint(toScale, courant)
} autre {
// ajout d'une autre condition pour empêcher l'erreur de point focal du zoom mobile
poêle(
origX + (current.clientX - startClientX) / échelle,
origY + (current.clientY - startClientY) / échelle,
{
animer : faux
}
);
}
}

Tous les 19 commentaires

Merci d'avoir ouvert un sujet. J'ai essayé la démo sur iOS et Android et je n'ai pas pu reproduire. Vous avez répertorié les navigateurs de bureau, mais le zoom par pincement est principalement destiné aux mobiles (bien que certains appareils disposent à la fois d'une souris et d'un écran tactile). Il peut être utile de savoir quel appareil vous utilisez, même si je ne serais probablement pas en mesure de le tester.

Je ne peux pas faire grand chose sans pouvoir reproduire le problème. Si vous creusez plus profondément et constatez qu'un changement de code dans Panzoom le résout (ou qu'un cas de test différent de la démo reproduit le problème), veuillez commenter ici et j'envisagerai un correctif.

Bonjour monsieur Willison ;

Merci pour votre réponse. J'ai utilisé les versions de bureau et mobile de
lesdits navigateurs. J'ai utilisé un Redmi Note 8T et un Galaxy 8 pour tester cela.

Pour voir ce problème, peut-être pouvez-vous jeter un œil à la démo que je développe ?
Tapez simplement un nom (rien n'est stocké, c'est juste un jeu pour enfants) et cliquez sur
sur le bouton "Exploració lliure" ; vous serez redirigé vers le Panzoom
image. Comme vous le verrez, le zoom de la molette de la souris fonctionne bien, mais le zoom par pincement (et
en fait, les boutons panzoom.zoomIn() et panzoom.zoomOut() déplacent le
image.

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

Je vous suis vraiment reconnaissant de votre aide et veuillez m'excuser pour la gêne occasionnée.

Cordialement;

Jorge Sanchez Blanco

El lun., 21 sept. 2020 à 19h45, Timmy Willison (<
[email protected]>) écrit :

Merci d'avoir ouvert un sujet. j'ai essayé la démo
https://timmywil.com/panzoom/demo sur iOS et Android et n'a pas pu
reproduire. Vous avez répertorié les navigateurs de bureau, mais le zoom par pincement est principalement destiné à
mobile (bien que certains appareils disposent à la fois d'une souris et d'un écran tactile). Il pourrait
être utile de savoir quel appareil vous utilisez, même si je serais probablement
impossible de tester dessus.

Je ne peux pas faire grand chose sans pouvoir reproduire le problème. Si
vous creusez plus profondément et trouvez qu'un changement de code dans Panzoom le corrige (ou qu'un
cas de test différent en plus de la démo reproduit le problème), s'il vous plaît
commentez ici et je vais envisager un patch.


Vous recevez ceci parce que vous êtes l'auteur du fil.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/timmywil/panzoom/issues/512#issuecomment-696267620 ,
ou désabonnez-vous
https://github.com/notifications/unsubscribe-auth/AOF4EAOK6YQVAHINOAQ3JZTSG6GMRANCNFSM4RUT4P7A
.

J'ai le même problème. Il semble que le point focal ne soit pas correctement calculé et qu'il soit tout en bas.

@jsblanco je vois. Panzoom s'appuie sur transform-origin: 50% 50% , qui centre l'animation au centre de la fenêtre plutôt qu'au centre de l'image, ce qui serait plus bas dans ce cas. Il déplace l'image en raison du paramètre contain: outside pour éviter que l'image ne descende trop bas. Je pense que cela peut être résolu en appelant zoomToPoint ou en utilisant zoom avec l'option focal la place et en trouvant le point dans la fenêtre qui est en fait le centre de l'image. Cela a-t-il du sens?

Je pourrais peut-être faire quelque chose comme ça par défaut lorsque contain: outside est défini.

@rmatec Utilisez -vous également contain: outside ?

Je n'utilise pas l'option contenant. Dans mon cas, il semble que le point focal soit en bas au centre. Le pincement vers l'intérieur ou vers l'extérieur se fait par rapport à ce point.

@rmatec Je pense qu'il doit y avoir une option en jeu, car je ne vois pas ce comportement dans les démos. Y a-t-il une autre option que vous définissez ?

J'utilise ce qui suit pour initialiser Panzoom.

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

Cela fonctionne parfaitement bien sur le bureau, mais pour une raison quelconque, ce n'est pas le cas sur mobile.

Ok, votre cas semble être différent. Pourriez-vous reproduire dans https://jsbin.com ou https://codepen.io et faire un nouveau ticket ? Voici un modèle qui peut être cloné https://jsbin.com/dibofogini/1/edit?html ,js,output.

Ça ira. Merci.

Pour une raison quelconque, lors de l'utilisation de l'option focale, l'image apparaît près de la
en bas à droite, et aucun autre zoom ne peut se produire, ni en avant ni en arrière.
Peut-être que je fais quelque chose de mal ? Dois-je passer des paramètres spécifiques
à panzoom.zoomIn() et .zoomOut() pour indiquer le point focal, ou simplement
l'inclure dans la déclaration initiale du panzoom devrait-il suffire ?

Pour ce que ça vaut, j'ai essayé les méthodes suivantes pour obtenir la focale
indiquer. J'ai aussi essayé de mettre des nombres bruts.

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

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

La suppression de "contain: outside" ne fait qu'afficher une image noire.

Le mar., 22 sept. 2020 à 15:59, Timmy Willison (<
[email protected]>) écrit :

@jsblanco https://github.com/jsblanco Je vois. Panzoom s'appuie sur transform-origin :
50% 50%, qui centre l'animation au centre de la fenêtre plutôt
que sur le centre de l'image, qui serait plus bas dans ce cas. Ce
déplace l'image en raison du paramètre contenant : extérieur pour empêcher la
l'image de descendre trop bas. Je pense que cela peut être résolu en appelant
zoomToPoint ou en utilisant le zoom avec l'option focale à la place et en trouvant
le point de la fenêtre qui est en fait le centre de l'image. Fait
c'est logique?

Je pourrais peut-être faire quelque chose comme ça par défaut lorsqu'il contient : extérieur
est défini.

@rmatec https://github.com/rmatec Utilisez-vous également contenir : à l'extérieur ?


Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/timmywil/panzoom/issues/512#issuecomment-696740708 ,
ou désabonnez-vous
https://github.com/notifications/unsubscribe-auth/AOF4EANBQXE5TDJOZNTBN6LSHCUVXANCNFSM4RUT4P7A
.

@jsblanco Désolé, c'est plus compliqué que ça. La façon de le faire serait de trouver le centre de l'image et de le traduire en son point dans la fenêtre parent du panzoom. Vous passeriez alors cela comme option focale, et elle devrait être calculée chaque fois que vous appelez le zoom. Cependant, laissez-moi voir si je peux vous trouver un exemple. Cela corrigerait zoomIn / zoomOut .

Cela dit, cela ne changerait pas le comportement du zoom par pincement. On peut dire que c'est la bonne chose à faire, car le zoom sur certains points se heurte à contain: outside . Je ne suis pas sûr de la solution, sauf peut-être de ne pas autoriser le zoom si l'image doit se déplacer afin de la conserver correctement dans la fenêtre d'affichage.

Ok, votre cas semble être différent. Pourriez-vous reproduire dans https://jsbin.com ou https://codepen.io et faire un nouveau ticket ? Voici un modèle qui peut être cloné https://jsbin.com/dibofogini/1/edit?html ,js,output.

J'ai créé https://github.com/timmywil/panzoom/issues/513 pour mon cas spécifique. Il y a un lien vers JSBin qui montre le problème.

Je suis capable de reproduire ce problème si je laisse "animer : vrai" activé.
Ce problème n'apparaît pas à "animate: false" - j'ai cloné votre modèle @timmywil pour reproduire ce problème :

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

(J'ai implémenté l'écouteur d'événement de roue pour zoomer directement - Si vous faites défiler assez rapidement, un changement de position se produira.)

D'accord, j'ai déplacé mon problème vers # 515 car bien que le problème soit le même, mais avec une configuration différente.

Salut;

Désolé d'avoir été long à répondre. Je ne pense pas que cela ait à voir avec container="outside"; Je viens de l'enlever et il présentait toujours le même comportement, mais pas aussi intensément. Le div panzoom et l'image ont cependant une taille fixe indépendante de celle de la rue ; cela pourrait-il faire partie du problème?

Merci

@jsblanco Le correctif devrait être le même.

Salut, j'allais ouvrir un nouveau problème sur le zoom de la roue qui s'éloigne du centre, mais j'ai parcouru celui-ci et j'ai pensé qu'il était suffisamment lié. Voici mes conclusions et la solution de contournement. Notez que je n'ai testé que dans les navigateurs sur un MacBook en utilisant le trackpad.

Je remarque que pour la démo de zoom du point focal , le centre flotte vers le haut à gauche lors du zoom dans Safari, Firefox. J'obtiens le même comportement même dans Chrome, mais uniquement lorsque l'inspecteur Web est ouvert.

J'ai donc commencé à l'examiner et je soupçonne que l'événement de la molette de la souris se déclenche trop souvent et que les choses ne se mettent pas à jour correctement en raison de la nature asynchrone de Panzoom . J'ai pensé que si j'essayais de réduire la fréquence du zoom, cela pourrait aider et bien sûr, cela semble "fonctionner". Vous pouvez le voir en action ici : https://jsbin.com/joliduwulo/1/edit?html ,js,output.

La mise en garde est que le zoom semblerait moins fluide. Dans cet exemple, je le limite à un zoom maximum toutes les 20 ms, mais lorsque je testais avec de gros SVG, en particulier dans Firefox, j'avais besoin de le régler à environ 50 ms pour qu'il ne perde pas le point focal.

@timmywil s'il vous plaît faites le moi savoir si vous voulez quand même que j'ouvre un nouveau sujet. Cela ressemble à un hack mais cela résout le problème pour moi. Si vous pensez que la solution vaut la peine d'être explorée, j'aimerais contribuer.

+1 sur la possibilité de se centrer sur l'élément panzoom plutôt que sur la fenêtre

Remplacer la fonction de déplacement sur panzoom.ts:426

fonction déplacer(événement : PointerEvent) {
si (
!isPanning ||
origX === non défini ||
origY === non défini ||
startClientX === non défini ||
startClientY === non défini
) {
retourner
}
addPointer(pointeurs, événement)
const courant = getMiddle(pointeurs)
si (pointeurs.longueur > 1) {
// Utilise la distance entre les 2 premiers pointeurs
// pour déterminer l'échelle courante
// empêche le problème de zoom sur mobile
si (startDistance === 0) {
startDistance = getDistance(pointeurs);
}
const diff = getDistance(pointeurs) - startDistance
const toScale = constrainScale((diff * options.step) / 80 + startScale).scale
zoomToPoint(toScale, courant)
} autre {
// ajout d'une autre condition pour empêcher l'erreur de point focal du zoom mobile
poêle(
origX + (current.clientX - startClientX) / échelle,
origY + (current.clientY - startClientY) / échelle,
{
animer : faux
}
);
}
}

Cette page vous a été utile?
0 / 5 - 0 notes